In Yii, while looking at the source code for CWebUser::logout, I've noticed that they use Yii::app()->getSession()->destroy() instead of the usual PHP session_destroy.
Doing a bit of research I saw that Yii has a class called CHttpSession with its own methods to store data.
This got me thinking - are they cross-compatible? Is CHttpSession just a nice wrapper? Or is it an all or nothing process?
In my custom code, I've been using $_SESSION to do all of my session-related stuff. While in things generated by Yii, I assume that it uses CHttpSession. Is it a problem to use both and mix them up?
I am now in the process of moving my session handling to AWS DynamoDB (https://github.com/aws/aws-sdk-php/blob/master/docs/feature-dynamodb-session-handler.rst), and before I add this additional layer, I want to make sure everything is compatible.
You can use Database based session to recover that. Its really simple. Just put
'session' => array(
'class'=>'CDbHttpSession',
'connectionID' => 'db'
),
on config/main.php components
CHttpSession is a nifty OO wrapper for php sessions. The underlying implementation uses php's session methods. Here's a snippet of part of the code for CHttpSession::open():
public function open()
{
if($this->getUseCustomStorage())
#session_set_save_handler( array($this,'openSession'),array($this,'closeSession'),array($this,'readSession'),array($this,'writeSession'),array($this,'destroySession'),array($this,'gcSession'));
#session_start();
For Yii convention, always use CHttpSession instead of $_SESSION.
Related
Within my app ("BIRD3"), I have a NodeJS server that uses the hprose RPC system to talk to a PHP server to query it run a request and return the result (the PHP server is multi-process and spawns a sub-process per request - for now). This proposes a few difficulties; headers, cookies, sessions.
In my Yii1 based app, I used an in-development branch of the runkit extension. But, as you can tell, this is super hacky, not clean, and dependency-wise, not a smart idea. But it worked, for the most part. Here is a snippet from that very bit of code I did:
<?php
// Header.
runkit_function_redefine("headers_sent", '', 'return false;');
runkit_function_redefine(
"header", '$to,$replace=false,$status=200',
'return HttpResponse::header($to);'
);
// We have a custom handler.
runkit_function_redefine(
"setcookie",
'$name,$value,$expire=0,$path="/",$domain=null,$secure=false,$httponly=false',
'return HttpResponse::setcookie($name,$value,$expire,$domain,$secure,$httponly);'
);
// Because...
runkit_function_redefine(
"session_regenerate_id",
'$deleteOld=false',
'return bird3_session_regenerate_id($deleteOld);'
);
Now, why did I need this? Simple: Yii does not have a direct way to override Session/Header/Cookie management without doing a good load of wiring of the internals. Overriding internal dependencies with extended, derived classes is not very easy and bulks up the config file a lot.
So my question is:
Does Laravel give me the possibility to extend a few classes, override methods that do Session and Header and Cookie management and enhance it to use my custom functions instead?
I'm writing a PHP application using zend framework 2.2.2.
I would like to know how to be able to use the FlashMessanger using zend framework 2.
now I know that it's possible to fetch the Flash Messanger using zf1 using the following code:
$this->messenger = Zend_Controller_Action_HelperBroker::getStaticHelper('flashMessenger');
how it is possible to fetch the flash messenger using zf2 ?
the thing is that I want to the flash messenger to be available in my own utility class
so I don't have the controller available to fetch the messenger from there.
any ideas?
thanks
The FlashMessenger is a ControllerPlugin Zend\Mvc\Controller\Plugin\FlashMessenger and that's where it makes the most sense of using it. Injecting the Messenger into your "UtilityClasses" to me sounds like a somewhat bad idea, since this would make the response-checking so much more complicated and the controllers quite more bloated. So take that in mind.
However it is possible to get the FlashMessenger into any class you want. The only catch is, all the classes you want the FM to be available at, have to be called by the ServiceManager. Your ServiceFactories then would look like this:
// Module#getServiceConfig()
return array('factories' => array(
'MyServiceClass' => function($serviceLocator) {
return new MyService(
$serviceLocator->get('controllerpluginmanager')->get('flashmessenger')
);
}
));
Of course you could re-write it to use setter-injection or even lazy-getters in your ServiceClass if you wish you inject the full ServiceLocator (which isn't advised).
I want to be able to call the CakeS3 plugin from the Cake Shell. However, as I understand it components cannot be loaded from the shell. I have read this post outlining strategies for overcoming it: using components in Cakephp 2+ Shell - however, I have had no success. The CakeS3 code here is similar to perfectly functioning cake S3 code in the rest of my app.
<?php
App::uses('Folder','Utility');
App::uses('File','Utility');
App::uses('CakeS3.CakeS3','Controller/Component');
class S3Shell extends AppShell {
public $uses = array('Upload', 'User', 'Comment');
public function main() {
$this->CakeS3 = new CakeS3.CakeS3(
array(
's3Key' => 'key',
's3Secret' => 'key',
'bucket' => 'bucket')
);
$this->out('Hello world.');
$this->CakeS3->permission('private');
$response = $this->CakeS3->putObject(WWW_ROOT . '/file.type' , 'file.type', $this->CakeS3->permission('private'));
if ($response == false){
echo "it failed";
} else {
echo "it worked";
}
}
This returns an error of "Fatal error: Class 'CakeS3' not found in /home/app/Console/Command/S3Shell.php. The main reason I am trying to get this to work is so I can automate some uploads with a cron. Of course, if there is a better way, I am all ears.
Forgive me this "advertising"... ;) but my plugin is probably better written and has a better architecture than this CakeS3 plugin if it is using a component which should be a model or behaviour task. Also it was made for exactly the use case you have. Plus it supports a few more storage systems than only S3.
You could do that for example in your shell:
StorageManager::adapter('S3')->write($key, StorageManager::adapter('Local')->read($key));
A file should be handled as an entity on its own that is associated to whatever it needs to be associated to. Every uploaded file (if you use or extend the models that come with the plugin, if not you have to take care of that) is stored as a single database entry that contains the name of the config that was used and some meta data for that file. If you do the line of code above in your shell you will have to keep record in the table if you want to access it this way later. Just check the examples in the readme.md out. You don't have to use the database table as a reference to your files but I really recommend the system the plugin implements.
Also, you might not be aware that WWW_ROOT is public accessible, so in the case you store sensitive data there it can be accessed publicly.
And finally in a shell you should not use echo but $this->out() for proper shell output.
I think the App:uses should look like:
App::uses('CakeS3', 'CakeS3.Controller/Component');
I'm the author of CakeS3, and no I'm afraid there is no "supported" way to do this as when we built this plugin, we didn't need to run uploads from shell and just needed a simple interface to S3 from our controllers. We then open sourced the plugin as a simple S3 connector.
If you'd like to have a go at modifying it to support shell access, I'd welcome a PR.
I don't have a particular road map for the plugin, so I've tagged your issue on github as an enhancement and will certainly consider it in future development, but I can't guarantee that it would fit your time requirements so that's why I mention you doing a PR.
I having issues with Codeigniter sessions dying on IE randomly, I search everywhere and tried everything, the bug just wouldnt dissappear, i tried the function to check if ajax and wont sess_update() not working either, so my question is, what is the setback if I initialize the CI session every controller call? I have both native and CI sessions, but It would take me a few more days to change everything to Native sessions. its a temp fix.
class Transactions extends Controller {
function Transactions()
{
session_start();
parent::Controller();
$this->load->model('Modelcontracts');
$this->load->model('Modelsignup');
$this->load->model('Modeltransactions');
$this->session->set_userdata('account_id',$_SESSION['account_id']);
$this->session->set_userdata('email',$_SESSION['email']);
$this->session->set_userdata('account_type',$_SESSION['account_type']);
$this->session->set_userdata('parent_account_id',$_SESSION['parent_account_id']);
$this->session->set_userdata('accountrole_id',$_SESSION['accountrole_id']);
$this->session->set_userdata('user_type_id',$_SESSION['user_type_id']);
}
function index()
{
I never experience any problems with CodeIgniters sessions. Have you created the MySQL table for ci_sessions?
The setback is basicly that it's an unlogical call. If that doesn't matter, then I can't see any setbacks with it.
You could ease up the code like this though:
$arr = array('account_id', 'email', 'account_type', 'parent_account_id', 'accountrole_id', 'user_type_id');
foreach($arr as $h)
if (isset($_SESSION[$h]))
$this->session->set_userdata($h, $_SESSION[$h]);
// else echo "Session [{$h}] doesn't exist!";
Or extend your session library to do a
foreach(array_keys($_SESSION) as $h)
$this->CI->session->set_userdata($h, $_SESSION[$h]);
When loaded.
I don't think you should be using session_start() if you're having CodeIgniter manage your sessions (which you are if you're using CodeIgniter's set_userdata() / get_userdata() functions).
It says right at the top of the CI user docs that CI doesn't use PHP's native session handling, so this may be causing you trouble. The session is started automatically by loading the session library, either automatically if you put it in the config file or explicitly with $this->load->library('session');.
http://codeigniter.com/user_guide/libraries/sessions.html
-Gus
Edit: I came across a CI forum post regarding IE/CI session issues. Apparently it's a well-known issue. http://codeigniter.com/forums/viewthread/211955/
My latest idea for do settings across my php project I am building was to store all my settings in a config PHP file, the php file will just return an array like this...
<?php
/**
* #Filename app-config.php
* #description Array to return to our config class
*/
return array(
'db_host' => 'localhost',
'db_name' => 'socialnetwork',
'db_user' => 'root',
'db_password' => '',
'site_path' => 'C:/webserver/htdocs/project/',
'site_url' => 'http://localhost/project/',
'image_path' => 'C:/webserver/htdocs/fproject/images/',
'image_url' => 'http://localhost/project/images/',
'site_name' => 'test site',
'admin_id' => 1,
'UTC_TIME' => gmdate('U', time()),
'ip' => $_SERVER['REMOTE_ADDR'],
'testtttt' => array(
'testtttt' => false
)
);
?>
Please note the actual config array is MUCH MUCH larger, many more items in it...
Then I would have a Config.class.php file that would load my array file and use the magic method __get($key). I can then autoload my config class file and access any site settings like this...
$config->ip;
$config->db_host;
$config->db_name;
$config->db_user;
So I realize this works great and is very flexible, in my class I can have it read in a PHP file with array like I am doing now, read INI file into array, read XML file into array, read JSON file into array. So it is very flexible for future projects but I am more concerned about performance for this particular project that I am working on now, it will be a social network site like facebook/myspace and I have had one before prior to this project and once I got around 100,000 user's performance became very important. So I am not "micro-optimizing" or "premature optimizing" I am stricly looking to do this the BEST way with performance in mind, it does not need to be flexible as I will only need it on this project.
So with that information, I always read about people trying to eliminate function calls as much as possible saying function calls cause more overhead. SO I am wanting to know from more experienced people what you think about this? I am new to using classes and objects in PHP, so is calling $config->db_user; as costly as calling a function in procedural like this getOption('db_user'); ? I am guessing it is the same as every time I would call a setting it is using the __get() method.
So for best performance should I go about this a different way? Like just loading my config array into a bootstrap file and accessing items when I need them like this...
$config['db_host'];
$config['db_username'];
$config['db_password'];
$config['ip'];
Please give me your thoughts on this without me having to do a bunch of benchmark test
From tests I've seen, I believe Alix Axel's response above is correct with respect to the relative speed of the four methods. Using a direct methods is the fastest, and using any sort of magic method usually is slower.
Also, in terms of optimization. The biggest performance hit for any single request in the system you describe will probably be the parsing of the XML/INI/JSON, rather than the accessing of it via whichever syntax you decide to go with. If you want to fix this, store the loaded data in APC once you parse it. This will come with the one caveat that you will want to only store static data in it, and not dynamic things like the UTC date.
Firstly, instead of an included file that returns an array I would instead use an .ini file and then use PHP's parse_ini_file() to load the settings.
Secondly, you shouldn't worry about function calls in this case. Why? Because you might have 100,000 users but if all 100,000 execute a script and need some config values then your 100,000 function calls are distributed over 100,000 scripts, which will be completely irrelevant as far as performance goes.
Function calls are only an issue if a single script execution, for example, executes 100,000 of them.
So pick whichever is the most natural implementation. Either an object or an array will work equally well. Actually an object has an advantage in that you can do:
$db = $config->database->hostname;
where $config->database can implicitly load just the database section of the INI file and will create another config object that can return the hostname entry. If you want to segment your config file this way.
IMO these are the fastest methods (in order):
$config['db_user']
$config->db_user directly
$config->db_user via __get()
getOption('db_user') via __get()
Also, you've already asked a lot of questions about your config system, not that I mind but I specifically remembered that you asked a question about whether you should use parse_ini_file() or not.
Why are you repeating the basically same questions over and over again?
I think you're taking premature optimization to a whole new level, you should worry about the performance of 100,000 users iff and when you get 50,000 users or so, not now.