how to use Zend_Loader_PluginLoader? - zend-framework

I am trying to optimize zend for performance.
I used as much cache as possible and got to the code of this page
where do i have to write it ? i tried putting it in bootstrap __initAutoload() but the profiler shows no change whatsover
$classFileIncCache = APPLICATION_PATH . '/../data/pluginLoaderCache.php';
if (file_exists($classFileIncCache)) {
include_once $classFileIncCache;
}
Zend_Loader_PluginLoader::setIncludeFileCache($classFileIncCache);
Can someone explain how to use it pluginloader and if it has a performance increase?
here is part of my bootstrap
protected function _initSessionAfterDb()
{
//http://stackoverflow.com/questions/1100562/zend-error-via-my-ini-file
$this->bootstrap('db');
$this->bootstrap('session');
}
protected function _initSession()
{
$this->bootstrap('cache');//http://stackoverflow.com/questions/5271018/zend-how-to-enable-cachemetadata-on-session-table
//NOTE: this config is also passed to Zend_Db_Table so anything specific
//to the table can be put in the config as well
$config = array(
'name' => 'session', //table name as per Zend_Db_Table
'primary' => array(
'session_id', //the sessionID given by PHP
'save_path', //session.save_path
'name', //session name
//'cols' => array('session_id', 'save_path', 'name', 'modified', 'lifetime', 'session_data')
),
'primaryAssignment' => array(
//you must tell the save handler which columns you
//are using as the primary key. ORDER IS IMPORTANT
'sessionId', //first column of the primary key is of the sessionID
'sessionSavePath', //second column of the primary key is the save path
'sessionName', //third column of the primary key is the session name
),
'modifiedColumn' => 'modified', //time the session should expire
'dataColumn' => 'session_data', //serialized data
'lifetimeColumn' => 'lifetime', //end of life for a specific record
'user_id' => 'user_id'
);
//Tell Zend_Session to use your Save Handler
$savehandler = new Zend_Session_SaveHandler_DbTable($config);
//http://framework.zend.com/wiki/display/ZFPROP/Zend_Session_SaveHandler_DbTable
//cookie persist for 30 min
$config = Zend_Registry::get('config');
$seconds = $config->session->seconds_life;
//make the session persist for 30 min
$savehandler->setLifetime($seconds)
->setOverrideLifetime(true);
Zend_Session::setSaveHandler($savehandler);
Zend_Session::start();
}

I think you are not starting on the good foot, early optimization is the root of all evil. First I think you should investigate which part of your application is the slowest and try to fix it, xdebug should be able to help to get some performance data.
The plugin loader cache would increase the performance but not by a great deal, the framework search in the filesystem the plugins you are using. Enabling the cache would skip the searching process but I doubt it would make your application 50% faster all suddendly.
Also to answer where you should write it, like you mentioned the bootstrap is probably the best place.

Related

CakePHP 3: Model Unit Test fails - "duplicate key value"

I'm using Postgres (which I think is related to the problem), and CakePHP 3.
I have the following unit test to just check to make sure that a valid dataset can get saved by the model. When I run the following test, with a standard "bake'd" Model unit test, I get the error below.
I think this is the problem:
We are using fixtures to add some base data. This is the only place that I think might be causing a problem. To add credence to this, while the unit tests were running I ran the following command to get the next auto-incrementing id value and it returned 1, even though it returned the proper number in non-test DB. Select nextval(pg_get_serial_sequence('agencies', 'id')) as new_id;
Unit Test:
public function testValidationDefault()
{
$agencyData = [
'full_name' => 'Agency Full Name',
'mode' => 'transit',
'request_api_class' => 'Rest\Get\Json',
'response_api_class' => 'NextBus\Generic',
'realtime_url_pattern' => 'http://api.example.com',
'routes' => '{"123": {"full_route": "123 Full Route", "route_color": "#123456"}}'
];
$agency = $this->Agencies->newEntity($agencyData);
$saved = $this->Agencies->save($agency);
$this->assertInstanceOf('App\Model\Entity\Agency', $saved);
}
Error:
PDOException: SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint "agencies_pkey"
DETAIL: Key (id)=(1) already exists.
Things I've tried
Copied that same code into a controller, and it successfully added the entity in the table.
Adding an id of 200. Same error appears.
Update 1
The fixture for this does have the ID field set each record. Deleting them from the fixture does work, but it breaks other unit tests that rely on some relational data.
I don't like this solution, but adding the following before saving the entity does work.
$this->Agencies->deleteAll('1=1');
[UPDATE: My other answer is the real solution to this problem.! You don't have to do this anymore...]
Here is a less dirty workaround that doesn't require deleting all the records:
use Cake\Datasource\ConnectionManager;
...
$connection = ConnectionManager::get('test');
$results = $connection->execute('ALTER SEQUENCE <tablename>_id_seq RESTART WITH 999999');
//TEST WHICH INSERTS RECORD(s)...
It appears that the auto-incrementing doesn't get properly set/reset during the setUp() or tearDown()... so manually setting it to something really high (greater than the number of existing records) prevents the "duplicate key..." error.
The benefit of this hack (over deleteAll('1=1')) is that you can still subsequently run tests that reference existing DB data.
It might be a problem in your fixture definition. The Cake PHP documentation uses a _constraints field specifying that the id field is a primary key:
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['id']],
]
I believe I've finally figured out the REAL solution to this problem!
I believe this issue stems from a default fixture setting that results from using the bake command to generate fixtures.
When you bake a model it creates the boilerplate for it's fixtures. Notice the autoIncrement for the ID property in the code below? Contrary to what you might think, this should not but true. When I set it to null and remove the ids from the items in the $records array I no longer get uniqueness errors.
public $fields = [
'id' => ['type' => 'integer', 'length' => 10, 'autoIncrement' => true, 'default' => null, 'null' => false, 'comment' => null, 'precision' => null, 'unsigned' => null],
'nickname' => ['type' => 'text', 'length' => null, 'default' => null, 'null' => false, 'comment' => null, 'precision' => null],
...
public $records = [
[
// 'id' => 1,
'nickname' => 'Foo bar',
'width' => 800,
...
The ninja wizards on the CakePHP project are the heroes: source
CakePHP ticket
If id fields are removed from fixture records then they will utilize auto-incrementing when inserted, leaving the table's ID sequence in the right place for inserts that happen during tests. I believe that is why it works for #emersonthis as described above.
That solution has another problem, though: you can't create dependable relationships between fixture records because you don't know what IDs they will get. What do you put in the foreign ID field of a related table? This has led me back to his original solution of just altering the table sequence after records with hard-coded IDs have been inserted. I do it like this in affected TestCases now:
public $fixtures = [
'app.articles',
'app.authors',
];
...
public function setUp()
{
$connection = \Cake\Datasource\ConnectionManager::get('test');
foreach ($this->fixtures as $fixture) {
$tableName = explode('.', $fixture)[1];
$connection->execute("
SELECT setval(
pg_get_serial_sequence('$tableName', 'id'),
(SELECT MAX(id) FROM $tableName)
)");
}
}
This moves the auto-increment sequence to the highest previously-used ID. The next time an ID is generated from the sequence it will be one higher, resolving the problem in all cases.
Including one of these solutions in an upcoming CakePHP release is being discussed here.

Set ttl and namespace using Memcached in Zend Framework 2

As far as I can figure this seems to be the way to set up Memcached and set the TTL and Namespace but they have no effect in the cache. The key is not prefixed with a namespace and the expire is infinite.
$MemcachedOptions = new \Zend\Cache\Storage\Adapter\MemcachedOptions();
$MemcachedResourceManager = new \Zend\Cache\Storage\Adapter\MemcachedResourceManager(1, new \Zend\Cache\Storage\Adapter\Memcached());
$MemcachedResourceManager->addServer(1, array('localhost', 11211));
$MemcachedOptions->setResourceManager($MemcachedResourceManager);
$MemcachedOptions->setNamespace('FooBar_');
$MemcachedOptions->setTtl(10);
$cache = $MemcachedOptions->getResourceManager()->getResource(1);
$cache->set('foobar_key','I am in cache');
Does anyone have any tips, clues? Any help would be much appreciated.
The MemcachedResourceManager works different as you trying to use it.
You should initialize it like the following:
// init a memcached resource manager with one native memcached resource
// using resource id "1"
$MemcachedResourceManager = new \Zend\Cache\Storage\Adapter\MemcachedResourceManager();
$MemcachedResourceManager->addServer('1', array('localhost', 11211));
// init a memcached storage adapter
// using the native memcached resource of id "1"
// configure it with a ttl and a namespace
$cache = \Zend\Cache\StorageFactory::adapterFactory('memcached', array(
'resource_manager' => $MemcachedResourceManager,
'resource_id' => '1',
'namespace' => 'FooBar_',
'ttl' => 10,
));
// or
$memcachedAdapterOptions = new \Zend\Cache\Storage\Adapter\MemcachedOptions(array(
'resource_manager' => $MemcachedResourceManager,
'resource_id' => '1',
'namespace' => 'FooBar_',
'ttl' => 10,
));
$cache = new \Zend\Cache\Storage\Adapter\Memcached($memcachedAdapterOptions);
How does the classes work together:
The most important class is Zend\Cache\Storage\Adapter\Memcached it is a wrapper for a native instance of Memcached used in a context of Zend\Cache\StorageInterface.
This storage adapter has a number of options defined as Zend\Cache\Storage\Adapter\MemcachedOptions.
Because cache storage adapters in ZF2 are designed to handle one type of items to store you need different instances of Zend\Cache\Storage\Adapter\Memcached for different type of items. But you don't wont to use different connections to a memcached (different instance of the native Memcached class) server - this is were Zend\Cache\Storage\Adapter\MemcachedResourceManager comes to play.
The Zend\Cache\Storage\Adapter\MemcachedResourceManager handles native instances of Memcached which will be used by Zend\Cache\Storage\Adapter\Memcached.

Can someone provide a php sample using nusoap/sugarcrm api to create an acct/lead in sugarcrn?

Can someone provide a sample code chunk of php using the sugarcrm API/nusoap for adding creating an acct. and then linking a lead to the acct?
I've got a sample function that adds a lead, and I can see how to create an acct, but I can't see how to tie a lead to the acct, to simulate the subpanel process in the sugarcrm acct/subpanel process.
thanks
// Create a new Lead, return the SOAP result
function createLead($data)
{
// Parse the data and store it into a name/value list
// which will then pe passed on to Sugar via SOAP
$name_value_list = array();
foreach($data as $key => $value)
array_push($name_value_list, array('name' => $key, 'value' => $value));
// Fire the set_entry call to the Leads module
$result = $this->soap->call('set_entry', array(
'session' => $this->session,
'module_name' => 'Leads',
'name_value_list' => $name_value_list
));
return $result;
}
$result = $sugar->createLead(array(
'lead_source' => 'Web Site',
'lead_source_description' => 'Inquiry form on the website',
'lead_status' => 'New',
'first_name' => $_POST['first_name'],
'last_name' => $_POST['last_name'],
'email1' => $_POST['email'],
'description' => $_POST['message']
));
You need to find the ID for the account and assign that ID to whatever the account_id field name is in the Lead Module. I have run into a couple things like this before and I have found it easier to go straight to the Sugar database. So, write a statement that will return the account is, for example: SELECT id WHERE something_in_the_account_table = something else;
Then you can assign that id in your $result array. I hope it helps. I didn't have any code or documentation in front of me or I would have helped more.

Zend_Cache cache file disappears

I have a zend cache which stores an array from the db. The cache can be read & updated fine. But the actual cache file seems to disappear after a day or so. I thought that adding automatic_cleaning_factor = 0 would solve this, but that doesn't seem to be the case.
$frontendOptions = array(
'caching' => true,
'cache_id_prefix' => 'mysite_blah',
'lifetime' => 14400, # 4 hours
'automatic_serialization' => true,
'automatic_cleaning_factor' => 0,
);
$backendOptions = array(
'cache_dir' => "{$_SERVER['DOCUMENT_ROOT']}/../../cache/zend_cache/"
);
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
if(!$result = $cache->load('test_blah'))
{
// run SQL
...
$cache->save($my_array_from_db, 'test_blah');
}
else
{
$result = $cache->load('test_blah');
}
The page which uses this cache isn't very popular, not sure if that has anything to do with it..... Any ideas?
I cannot explain why your file is vanishing, I think something is missing from your sample that is probably removing the cache file. I can however have a few notes that might help you out...
I think you're misinterpreting the automatic_cleaning_factor parameter. This does not disable your cache from expiring. This only disables the cache frontend from automatically cleaning any cache that may have expired when you call the save() method.
When you load() your cache it still gets tested for validity, and if invalid, it gets ignored and your database will be queried for fresh data. You can pass true as a second parameter on the load() to ignore the validity test.
However you should probably just set your lifetime to a very long time instead of overriding cache validation, because it's there for a reason.
Also, this code can be simplified:
if(!$result = $cache->load('test_blah')) {
// run SQL
...
$cache->save($my_array_from_db, 'test_blah');
} else {
$result = $cache->load('test_blah');
}
To:
if(!$result = $cache->load('test_blah')) {
// run SQL
...
$result = $my_array_from_db;
$cache->save($result, 'test_blah');
}
The else is not needed because $result from your cache is assigned in the if() statement.

Zend Sessions getting mixed up

I'm currently working on the login for a Zend Framework application, and I'm using a combination of Zend_Auth and Zend_Session using a database adapter (as described in the Zend Framework manuals).
I've made a resource for the session:
class DC_Resource_DbSession extends Zend_Application_Resource_ResourceAbstract{
public function init(){
}
public function setadapter($value){
$this->dbAdapter = $value;
}
public function setSession($adapter){
//put your code here
$config = array(
'name' => 'sessions',
'primary' => 'id',
'modifiedColumn' => 'modified',
'dataColumn' => 'data',
'lifetimeColumn' => 'lifetime',
'db' => $adapter
);
Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_DbTable($config));
Zend_Session::setOptions(array('name'=>'MY_SESSION_NAME'));
Zend_Session::start();
}
}
Zend Auth then uses the session to store some rudimentary authentication information.
However, when testing the login (from the same IP) if one user in our office logs in and another user goes to the site, they are logged in as the user!!! Can anyone help me figure out why they are using each other's sessions?
DOH!!!!
My humble, humiliated apologies. The id column datatype had been set to INT by our migrations guy - and obviously it needs to be VARCHAR....
smacks self in face...