Fatal error: Class 'CI_Controller' not found - codeigniter

When I try to access the localhost for my xampp server, an error shows up like this:
Fatal error: Class 'CI_Controller' not found in
C:\xampp\htdocs\system\core\CodeIgniter.php on line 226
CodeIgniter.php line 222-227:
require BASEPATH.'core/Controller.php';
function &get_instance()
{
return CI_Controller::get_instance();
}
Full CodeIgniter.php
<?php
if (!defined('BASEPATH')) {
exit('No direct script access allowed');
}
/*
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
*
* #package CodeIgniter
* #author ExpressionEngine Dev Team
* #copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* #license http://codeigniter.com/user_guide/license.html
* #link http://codeigniter.com
* #since Version 1.0
* #filesource
*/
// ------------------------------------------------------------------------
/*
* System Initialization File
*
* Loads the base classes and executes the request.
*
* #package CodeIgniter
* #subpackage codeigniter
* #category Front-controller
* #author ExpressionEngine Dev Team
* #link http://codeigniter.com/user_guide/
*/
/*
* CodeIgniter Version
*
* #var string
*
*/
define('CI_VERSION', '2.2.0');
/*
* CodeIgniter Branch (Core = TRUE, Reactor = FALSE)
*
* #var boolean
*
*/
define('CI_CORE', false);
/*
* ------------------------------------------------------
* Load the global functions
* ------------------------------------------------------
*/
require BASEPATH.'core/Common.php';
/*
* ------------------------------------------------------
* Load the framework constants
* ------------------------------------------------------
*/
if (defined('ENVIRONMENT') and
file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php')) {
require APPPATH.'config/'.ENVIRONMENT.'/constants.php';
} else {
require APPPATH.'config/constants.php';
}
/*
* ------------------------------------------------------
* Define a custom error handler so we can log PHP errors
* ------------------------------------------------------
*/
set_error_handler('_exception_handler');
if (!is_php('5.3')) {
#set_magic_quotes_runtime(0); // Kill magic quotes
}
/*
* ------------------------------------------------------
* Set the subclass_prefix
* ------------------------------------------------------
*
* Normally the "subclass_prefix" is set in the config file.
* The subclass prefix allows CI to know if a core class is
* being extended via a library in the local application
* "libraries" folder. Since CI allows config items to be
* overriden via data set in the main index. php file,
* before proceeding we need to know if a subclass_prefix
* override exists. If so, we will set this value now,
* before any classes are loaded
* Note: Since the config file data is cached it doesn't
* hurt to load it here.
*/
if (isset($assign_to_config['subclass_prefix']) and $assign_to_config['subclass_prefix'] != '') {
get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
}
/*
* ------------------------------------------------------
* Set a liberal script execution time limit
* ------------------------------------------------------
*/
if (function_exists('set_time_limit') == true and #ini_get('safe_mode') == 0) {
#set_time_limit(300);
}
/*
* ------------------------------------------------------
* Start the timer... tick tock tick tock...
* ------------------------------------------------------
*/
$BM = &load_class('Benchmark', 'core');
$BM->mark('total_execution_time_start');
$BM->mark('loading_time:_base_classes_start');
/*
* ------------------------------------------------------
* Instantiate the hooks class
* ------------------------------------------------------
*/
$EXT = &load_class('Hooks', 'core');
/*
* ------------------------------------------------------
* Is there a "pre_system" hook?
* ------------------------------------------------------
*/
$EXT->_call_hook('pre_system');
/*
* ------------------------------------------------------
* Instantiate the config class
* ------------------------------------------------------
*/
$CFG = &load_class('Config', 'core');
// Do we have any manually set config items in the index.php file?
if (isset($assign_to_config)) {
$CFG->_assign_to_config($assign_to_config);
}
/*
* ------------------------------------------------------
* Instantiate the UTF-8 class
* ------------------------------------------------------
*
* Note: Order here is rather important as the UTF-8
* class needs to be used very early on, but it cannot
* properly determine if UTf-8 can be supported until
* after the Config class is instantiated.
*
*/
$UNI = &load_class('Utf8', 'core');
/*
* ------------------------------------------------------
* Instantiate the URI class
* ------------------------------------------------------
*/
$URI = &load_class('URI', 'core');
/*
* ------------------------------------------------------
* Instantiate the routing class and set the routing
* ------------------------------------------------------
*/
$RTR = &load_class('Router', 'core');
$RTR->_set_routing();
// Set any routing overrides that may exist in the main index file
if (isset($routing)) {
$RTR->_set_overrides($routing);
}
/*
* ------------------------------------------------------
* Instantiate the output class
* ------------------------------------------------------
*/
$OUT = &load_class('Output', 'core');
/*
* ------------------------------------------------------
* Is there a valid cache file? If so, we're done...
* ------------------------------------------------------
*/
if ($EXT->_call_hook('cache_override') === false) {
if ($OUT->_display_cache($CFG, $URI) == true) {
exit;
}
}
/*
* -----------------------------------------------------
* Load the security class for xss and csrf support
* -----------------------------------------------------
*/
$SEC = &load_class('Security', 'core');
/*
* ------------------------------------------------------
* Load the Input class and sanitize globals
* ------------------------------------------------------
*/
$IN = &load_class('Input', 'core');
/*
* ------------------------------------------------------
* Load the Language class
* ------------------------------------------------------
*/
$LANG = &load_class('Lang', 'core');
/*
* ------------------------------------------------------
* Load the app controller and local controller
* ------------------------------------------------------
*
*/
// Load the base controller class
require BASEPATH.'core/Controller.php';
function &get_instance()
{
return CI_Controller::get_instance();
}
if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php')) {
require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
}
// Load the local application controller
// Note: The Router class automatically validates the controller path using the router->_validate_request().
// If this include fails it means that the default controller in the Routes.php file is not resolving to something valid.
if (!file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php')) {
show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.');
}
include APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php';
// Set a mark point for benchmarking
$BM->mark('loading_time:_base_classes_end');
/*
* ------------------------------------------------------
* Security check
* ------------------------------------------------------
*
* None of the functions in the app controller or the
* loader class can be called via the URI, nor can
* controller functions that begin with an underscore
*/
$class = $RTR->fetch_class();
$method = $RTR->fetch_method();
if (!class_exists($class)
or strncmp($method, '_', 1) == 0
or in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller')))
) {
if (!empty($RTR->routes['404_override'])) {
$x = explode('/', $RTR->routes['404_override']);
$class = $x[0];
$method = (isset($x[1]) ? $x[1] : 'index');
if (!class_exists($class)) {
if (!file_exists(APPPATH.'controllers/'.$class.'.php')) {
show_404("{$class}/{$method}");
}
include_once APPPATH.'controllers/'.$class.'.php';
}
} else {
show_404("{$class}/{$method}");
}
}
/*
* ------------------------------------------------------
* Is there a "pre_controller" hook?
* ------------------------------------------------------
*/
$EXT->_call_hook('pre_controller');
/*
* ------------------------------------------------------
* Instantiate the requested controller
* ------------------------------------------------------
*/
// Mark a start point so we can benchmark the controller
$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');
$CI = new $class();
/*
* ------------------------------------------------------
* Is there a "post_controller_constructor" hook?
* ------------------------------------------------------
*/
$EXT->_call_hook('post_controller_constructor');
/*
* ------------------------------------------------------
* Call the requested method
* ------------------------------------------------------
*/
// Is there a "remap" function? If so, we call it instead
if (method_exists($CI, '_remap')) {
$CI->_remap($method, array_slice($URI->rsegments, 2));
} else {
// is_callable() returns TRUE on some versions of PHP 5 for private and protected
// methods, so we'll use this workaround for consistent behavior
if (!in_array(strtolower($method), array_map('strtolower', get_class_methods($CI)))) {
// Check and see if we are using a 404 override and use it.
if (!empty($RTR->routes['404_override'])) {
$x = explode('/', $RTR->routes['404_override']);
$class = $x[0];
$method = (isset($x[1]) ? $x[1] : 'index');
if (!class_exists($class)) {
if (!file_exists(APPPATH.'controllers/'.$class.'.php')) {
show_404("{$class}/{$method}");
}
include_once APPPATH.'controllers/'.$class.'.php';
unset($CI);
$CI = new $class();
}
} else {
show_404("{$class}/{$method}");
}
}
// Call the requested method.
// Any URI segments present (besides the class/function) will be passed to the method for convenience
call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
}
// Mark a benchmark end point
$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');
/*
* ------------------------------------------------------
* Is there a "post_controller" hook?
* ------------------------------------------------------
*/
$EXT->_call_hook('post_controller');
/*
* ------------------------------------------------------
* Send the final rendered output to the browser
* ------------------------------------------------------
*/
if ($EXT->_call_hook('display_override') === false) {
$OUT->_display();
}
/*
* ------------------------------------------------------
* Is there a "post_system" hook?
* ------------------------------------------------------
*/
$EXT->_call_hook('post_system');
/*
* ------------------------------------------------------
* Close the DB connection if one exists
* ------------------------------------------------------
*/
if (class_exists('CI_DB') and isset($CI->db)) {
$CI->db->close();
}
/* End of file CodeIgniter.php */
/* Location: ./system/core/CodeIgniter.php */
Full Controller.php
<?php
if (!defined('BASEPATH')) {
exit('No direct script access allowed');
}
/**
* CodeIgniter.
*
* An open source application development framework for PHP 5.1.6 or newer
*
* #author ExpressionEngine Dev Team
* #copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
* #license http://codeigniter.com/user_guide/license.html
*
* #link http://codeigniter.com
* #since Version 1.0
* #filesource
*/
// ------------------------------------------------------------------------
/**
* CodeIgniter Application Controller Class.
*
* This class object is the super class that every library in
* CodeIgniter will be assigned to.
*
* #category Libraries
*
* #author ExpressionEngine Dev Team
*
* #link http://codeigniter.com/user_guide/general/controllers.html
*/
class CI_Controller
{
private static $instance;
/**
* Constructor.
*/
public function __construct()
{
self::$instance = &$this;
// Assign all the class objects that were instantiated by the
// bootstrap file (CodeIgniter.php) to local class variables
// so that CI can run as one big super object.
foreach (is_loaded() as $var => $class) {
$this->$var = &load_class($class);
}
$this->load = &load_class('Loader', 'core');
$this->load->initialize();
log_message('debug', 'Controller Class Initialized');
}
public static function &get_instance()
{
return self::$instance;
}
}
// END Controller class
/* End of file Controller.php */
/* Location: ./system/core/Controller.php */
thanks for you time

what will you do?
if just call a controller class. you can write the controller like this.
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class YourControllerName extends CI_Controller {
}

I had this issue and the actual cause of this error was my wrong database configuration settings. It was a kind of misleading error message.
Fixing my database configuration settings present inside application/config folder solved the issue for me.
This article was helpful which pointed me to look in the database configuration file.

I faced the same issue 'Ci_Controller not found in /Codeigniter.php line 234
with CI framework 2.2.1 version.
1- I ve downloaded the same project version from github
2- I moved all of my controllers,models,views,assets from my origin project to the new downloaded project
Then it's working, unfortunately without knowing the source of the issue.

Related

There is an error when i would to run php artisan serve

Warning: require_once(C:\xampp\htdocs\local/public/index.php): failed to open stream: No such file or directory in C:\xampp\htdocs\local\server.php on line 21
Fatal error: require_once(): Failed opening required 'C:\xampp\htdocs\local/public/index.php' (include_path='C:\xampp\php\PEAR') in C:\xampp\htdocs\local\server.php on line 21
This is what's inside the server.php file
<?php
namespace Illuminate\Foundation\Console;
use Illuminate\Console\Command;
use Illuminate\Support\ProcessUtils;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Process\PhpExecutableFinder;
class ServeCommand extends Command
{
/**
* The console command name.
*
* #var string
*/
protected $name = 'serve';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Serve the application on the PHP development server';
/**
* Execute the console command.
*
* #return void
*
* #throws \Exception
*/
public function handle()
{
chdir('/');
$this->line("<info>Laravel development server started:</info> <http://{$this->host()}:{$this->port()}>");
passthru($this->serverCommand());
}
/**
* Get the full server command.
*
* #return string
*/
protected function serverCommand()
{
return sprintf('%s -S %s:%s %s/server.php',
ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false)),
$this->host(),
$this->port(),
ProcessUtils::escapeArgument(base_path())
);
}
/**
* Get the host for the command.
*
* #return string
*/
protected function host()
{
return $this->input->getOption('host');
}
/**
* Get the port for the command.
*
* #return string
*/
protected function port()
{
return $this->input->getOption('port');
}
/**
* Get the console command options.
*
* #return array
*/
protected function getOptions()
{
return [
['host', null, InputOption::VALUE_OPTIONAL, 'The host address to serve the application on.', '127.0.0.1'],
['port', null, InputOption::VALUE_OPTIONAL, 'The port to serve the application on.', 8000],
];
}
}
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* #package Laravel
* #author Taylor Otwell <taylor#laravel.com>
*/
$uri = urldecode(
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
);
// This file allows us to emulate Apache's "mod_rewrite" functionality from the
// built-in PHP web server. This provides a convenient way to test a Laravel
// application without having installed a "real" web server software here.
if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
return false;
}
require_once __DIR__.'/public/index.php';
Change what's in your server to this

error rtrim() in vendor\laravel\framework\src\Illuminate\Foundation\Application.php

/*When I try to view the output of my project on the browser, I am redirected to the following error
"ErrorException (E_WARNING)rtrim () expects the parameter 1 to be
string, given the object ".
Can someone help me?
*/
i find the problem in following function public function setBasePath($basePath ){
below the code Application.php:
<?php
namespace Illuminate\Foundation;
use Closure;
use RuntimeException;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Container\Container;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Log\LogServiceProvider;
use Illuminate\Support\ServiceProvider;
use Illuminate\Events\EventServiceProvider;
use Illuminate\Routing\RoutingServiceProvider;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Contracts\Http\Kernel as HttpKernelContract;
use Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables;
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Illuminate\Contracts\Foundation\Application as ApplicationContract;
class Application extends Container implements ApplicationContract, HttpKernelInterface
{
/**
* The Laravel framework version.
*
* #var string
*/
const VERSION = '5.6.39';
/**
* The base path for the Laravel installation.
*
* #var string
*/
protected $basePath;
/**
* Indicates if the application has been bootstrapped before.
*
* #var bool
*/
protected $hasBeenBootstrapped = false;
/**
* Indicates if the application has "booted".
*
* #var bool
*/
protected $booted = false;
/**
* The array of booting callbacks.
*
* #var array
*/
protected $bootingCallbacks = [];
/**
* The array of booted callbacks.
*
* #var array
*/
protected $bootedCallbacks = [];
/**
* The array of terminating callbacks.
*
* #var array
*/
protected $terminatingCallbacks = [];
/**
* All of the registered service providers.
*
* #var array
*/
protected $serviceProviders = [];
/**
* The names of the loaded service providers.
*
* #var array
*/
protected $loadedProviders = [];
/**
* The deferred services and their providers.
*
* #var array
*/
protected $deferredServices = [];
/**
* The custom database path defined by the developer.
*
* #var string
*/
protected $databasePath;
/**
* The custom storage path defined by the developer.
*
* #var string
*/
protected $storagePath;
/**
* The custom environment path defined by the developer.
*
* #var string
*/
protected $environmentPath;
/**
* The environment file to load during bootstrapping.
*
* #var string
*/
protected $environmentFile = '.env';
/**
* The application namespace.
*
* #var string
*/
protected $namespace;
/**
* Create a new Illuminate application instance.
*
* #param string|null $basePath
* #return void
*/
public function __construct($basePath = null)
{
if ($basePath) {
$this->setBasePath($basePath);
}
$this->registerBaseBindings();
$this->registerBaseServiceProviders();
$this->registerCoreContainerAliases();
}
/**
* Get the version number of the application.
*
* #return string
*/
public function version()
{
return static::VERSION;
}
/**
* Register the basic bindings into the container.
*
* #return void
*/
protected function registerBaseBindings()
{
static::setInstance($this);
$this->instance('app', $this);
$this->instance(Container::class, $this);
$this->instance(PackageManifest::class, new PackageManifest(
new Filesystem, $this->basePath(), $this->getCachedPackagesPath()
));
}
/**
* Register all of the base service providers.
*
* #return void
*/
protected function registerBaseServiceProviders()
{
$this->register(new EventServiceProvider($this));
$this->register(new LogServiceProvider($this));
$this->register(new RoutingServiceProvider($this));
}
/**
* Run the given array of bootstrap classes.
*
* #param array $bootstrappers
* #return void
*/
public function bootstrapWith(array $bootstrappers)
{
$this->hasBeenBootstrapped = true;
foreach ($bootstrappers as $bootstrapper) {
$this['events']->fire('bootstrapping: '.$bootstrapper, [$this]);
$this->make($bootstrapper)->bootstrap($this);
$this['events']->fire('bootstrapped: '.$bootstrapper, [$this]);
}
}
/**
* Register a callback to run after loading the environment.
*
* #param \Closure $callback
* #return void
*/
public function afterLoadingEnvironment(Closure $callback)
{
return $this->afterBootstrapping(
LoadEnvironmentVariables::class, $callback
);
}
/**
* Register a callback to run before a bootstrapper.
*
* #param string $bootstrapper
* #param \Closure $callback
* #return void
*/
public function beforeBootstrapping($bootstrapper, Closure $callback)
{
$this['events']->listen('bootstrapping: '.$bootstrapper, $callback);
}
/**
* Register a callback to run after a bootstrapper.
*
* #param string $bootstrapper
* #param \Closure $callback
* #return void
*/
public function afterBootstrapping($bootstrapper, Closure $callback)
{
$this['events']->listen('bootstrapped: '.$bootstrapper, $callback);
}
/**
* Determine if the application has been bootstrapped before.
*
* #return bool
*/
public function hasBeenBootstrapped()
{
return $this->hasBeenBootstrapped;
}
/**
* Set the base path for the application.
*
* #param string $basePath
* #return $this
*/
public function setBasePath($basePath )
{
$this->basePath = rtrim($basePath, '\/');
$this->bindPathsInContainer();
return $this;
}
/**
* Bind all of the application paths in the container.
*
* #return void
*/
protected function bindPathsInContainer()
{
$this->instance('path', $this->path());
$this->instance('path.base', $this->basePath());
$this->instance('path.lang', $this->langPath());
$this->instance('path.config', $this->configPath());
$this->instance('path.public', $this->publicPath());
$this->instance('path.storage', $this->storagePath());
$this->instance('path.database', $this->databasePath());
$this->instance('path.resources', $this->resourcePath());
$this->instance('path.bootstrap', $this->bootstrapPath());
}
/**
* Get the path to the application "app" directory.
*
* #param string $path Optionally, a path to append to the app path
* #return string
*/
public function path($path = '')
{
return $this->basePath.DIRECTORY_SEPARATOR.'app'.($path ? DIRECTORY_SEPARATOR.$path : $path);
}
/**
* Get the base path of the Laravel installation.
*
* #param string $path Optionally, a path to append to the base path
* #return string
*/
public function basePath($path = '')
{
return $this->basePath.($path ? DIRECTORY_SEPARATOR.$path : $path);
}
/**
* Get the path to the bootstrap directory.
*
* #param string $path Optionally, a path to append to the bootstrap path
* #return string
*/
public function bootstrapPath($path = '')
{
return $this->basePath.DIRECTORY_SEPARATOR.'bootstrap'.($path ? DIRECTORY_SEPARATOR.$path : $path);
}
/**
* Get the path to the application configuration files.
*
* #param string $path Optionally, a path to append to the config path
* #return string
*/
public function configPath($path = '')
{
return $this->basePath.DIRECTORY_SEPARATOR.'config'.($path ? DIRECTORY_SEPARATOR.$path : $path);
}
/**
* Get the path to the database directory.
*
* #param string $path Optionally, a path to append to the database path
* #return string
*/
public function databasePath($path = '')
{
return ($this->databasePath ?: $thi`enter code here`s->basePath.DIRECTORY_SEPARATOR.'database').($path ? DIRECTORY_SEPARATOR.$path : $path);
}
Can you check you .env for APP_BASE_PATH?
The Application is initialized in bootstrap/app.php file
$app = new Illuminate\Foundation\Application(
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
As you can see it looks APP_BASE_PATH environment variable and if this is not set it uses the path to your root application folder.
dirname(__DIR__) returns the path to the parent folder.
Based on the details you posted it looks like the problem can be with the value you set for APP_BASE_PATH
This response assumes you are using the latest version of Laravel, 5.8

Multiple methods for action in API Platform

I'm writing a custom action and I need to make it available for both GET (collection) and POST methods.
My annotation looks like this.
/**
* #Route(
* name="api_entity_custom",
* path="/entity/custom",
* defaults={
* "_api_resource_class"=Entity::class,
* "_api_collection_operation_name"="EntityCustom"
* }
* )
* #Method("GET")
*/
That works for GET, but when I add POST then I only see GET in docs (swagger)
#Method({"GET", "POST"})
If I change the order then I see POST but not GET
#Method({"POST", "GET"})
Is it possible to do this? How?
EDIT:
I'm using a structure like this
//Path/To/Entity/Action/EntityCustomAction.php
class EntityCustomAction
{
/**
* #Route(
* name="api_entity_custom",
* path="/entity/custom",
* defaults={
* "_api_resource_class"=Entity::class,
* "_api_collection_operation_name"="EntityCustom"
* }
* )
* #Method("GET")
*/
public function __invoke($data)
{
...
which is enabled in routing
entity:
resource: '#EntityBundle/Action/'
type: 'annotation'
You can do it in following way:
Action 1:
/**
* #Route("/data/save", name="data_save")
* #Method({"GET"})
* #Template()
*/
public function dataSaveViewAction()
{
// code here...
}
Action 2:
/**
* #Route("/data/save", name="data_save")
* #Method({"POST"})
*/
public function dataSaveAction(Request $request)
{
// code here ...
}
The problem here is that you are using the same name for both actions. However, the name of a route must be unique. If not, API-Platform won't display it. You should do something like this :
Action 1:
/**
* #Route("/data/save", name="data_save_get") // Choose a unique name
* #Method({"GET"})
* #Template()
*/
public function dataSaveViewAction()
{
// code here...
}
Action 2:
/**
* #Route("/data/save", name="data_save_post") // same here
* #Method({"POST"})
*/
public function dataSaveAction(Request $request)
{
// code here ...
}

Is it safe to use CodeIgniter shopping cart?

According to CodeIgniter documentation their Shopping Cart Class "is DEPRECATED and should not be used".
Is there any harm in going ahead and using it? It is a very close match to what I need and I cannot see a similar library anywhere else.
using codeigniter cart class is fine as long as the session class is secure, but ci 2.x session is not secure since it saves its data in a cookie "ci_session" so the end user can modify session data (including cart data)
to overcome this vulnerability you can use a session extension that doesn't save any session data in the browser cookie, you can use something like EckoTools Session Library , that you put in your libraries/session.php and use it as you use ci native session , and here is the library code :
note: this library assumes that you are using the database to save session data , so you should enable this $config['sess_use_database'] = TRUE; in your config.php file
<?php
/**
The EckoTools Session Library
#package The EckoTools Session Library
#category Libraries
#author Hartmut König (h.koenig#eckotools.com)
#link http://www.okidoe.de
#version 1.0.2
#copyright Hartmut König 2009
A class to handle sessions by using a mySQL database for session related
data storage providing better security then the default session handler
used by PHP with added protection against Session Hijacking & Fixation
including the flashdata-Feature of CI. It don't use Browser or IP to identify
the user. Instead I generate a fingerprint of different seldom changing data
(#link _generate_fingerprint)
To prevent session hijacking, don't forget to use the {#link regenerate_id}
method whenever you do a privilege change in your application
--
-- MYSQL: Table structure for table `ci_sessions`
--
CREATE TABLE `ci_sessions` (
`session_id` varchar(32) NOT NULL default '',
`fingerprint` varchar(32) NOT NULL default '',
`session_data` blob NOT NULL,
`session_expire` int(11) NOT NULL default '0',
PRIMARY KEY (`session_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
This class is an adaptation between the original CI Sessions, Native Sessions
and my own coding
*/
error_reporting(E_ALL);
class CI_Session
{
/**
* Constructor of class
*
* Initializes the class and starts a new session
*
* There is no need to call start_session() after instantiating this class
*
* $gc_maxlifetime (optional) the number of seconds after which data will be seen as 'garbage' and
* cleaned up on the next run of the gc (garbage collection) routine
*
* Default is specified in php.ini file
*
* $gc_probability (optional) used in conjunction with gc_divisor, is used to manage probability that
* the gc routine is started. the probability is expressed by the formula
*
* probability = $gc_probability / $gc_divisor
*
* So if $gc_probability is 1 and $gc_divisor is 100 means that there is
* a 1% chance the the gc routine will be called on each request
*
* Default is specified in php.ini file
*
* $gc_divisor (optional) used in conjunction with gc_probability, is used to manage probability
* that the gc routine is started. the probability is expressed by the formula
*
* probability = $gc_probability / $gc_divisor
*
* So if $gc_probability is 1 and $gc_divisor is 100 means that there is
* a 1% chance the the gc routine will be called on each request
*
* Default is specified in php.ini file
*
* $security_code (optional) the value of this argument is appended to the fingerprint before
* creating the md5 hash out of it. this way we'll try to prevent fingerprint
* spoofing
*
* Default is 'LeouOeEkKpvSnD-YCHd5ogt3y'
*
* $table_name (optional) You can change the name of that table by setting this property
*
* Default is 'ci_sessions'
*
* #return void
*/
function CI_Session( $security_code="LeouOeEkKpvSnD-YCHd5ogt3y",$table_name="ci_sessions" )
{
//-- CI Config
$this->CI = & get_instance();
$this->flashdata_key = 'flash'; // prefix for "flash" variables (eg. flash:new:message)
$table_name = $this->CI->config->item('sess_table_name');
$gc_maxlifetime = $this->CI->config->item('sess_expiration');
$gc_probability = $this->CI->config->item('sess_gc_probability');
$gc_divisor = $this->CI->config->item('sess_gc_divisor');
$sess_name = $this->CI->config->item('sess_cookie_name');
// if $gc_maxlifetime is specified and is an integer number
(!empty($gc_maxlifetime) && is_integer($gc_maxlifetime))
? #ini_set('session.gc_maxlifetime', $gc_maxlifetime)
: false;
// if $gc_probability is specified and is an integer number
(!empty($gc_probability) && is_integer($gc_probability))
? #ini_set('session.gc_probability', $gc_probability)
: false;
// if $gc_divisor is specified and is an integer number
(!empty($gc_divisor) && is_integer($gc_divisor))
? #ini_set('session.gc_divisor', $gc_divisor)
: false;
(!empty($sess_name))
? #ini_set('session.name', $sess_name)
: false;
// get session lifetime
$this->sessionLifetime = ini_get("session.gc_maxlifetime");
// we'll use this later in order to prevent fingerprint spoofing
$this->securityCode = $security_code;
$this->tableName = $table_name;
// register the new handler
session_set_save_handler(
array(&$this, '_open'),
array(&$this, '_close'),
array(&$this, '_read'),
array(&$this, '_write'),
array(&$this, '_destroy'),
array(&$this, '_gc')
);
register_shutdown_function('session_write_close');
// start the session
session_start();
// Delete 'old' flashdata (from last request)
$this->_flashdata_sweep();
// Mark all new flashdata as old (data will be deleted before next request)
$this->_flashdata_mark();
}
/**
* Reads given session attribute value
*
* #return integer sessionvalue
*/
function userdata($item)
{
//added for backward-compatibility
if($item == 'session_id')
{
return session_id();
}
if(isset($_SESSION[$item]))
{
return($_SESSION[$item]);
}
return(false);
}
/**
* Fetch all session data
*
* #access public
* #return mixed
*/
function all_userdata()
{
return ( ! isset($_SESSION)) ? FALSE : $_SESSION;
}
/**
* Sets session attributes to the given values
*
* #return void
*/
function set_userdata($newdata = array(), $newval = '')
{
(is_string($newdata))
? $newdata = array($newdata => $newval)
: false;
if(count($newdata) > 0)
{
foreach($newdata as $key => $val)
{
$_SESSION[$key] = $val;
}
}
}
/**
* Erases given session attributes
*
* #return void
*/
function unset_userdata($newdata = array())
{
(is_string($newdata))
? $newdata = array($newdata => '')
: false;
if(count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
unset($_SESSION[$key]);
}
}
}
/**
* Deletes all data related to the session
* #return void
*/
function sess_destroy()
{
$this->regenerate_id();
session_unset();
session_destroy();
}
/**
* Regenerates the session id.
*
* <b>Call this method whenever you do a privilege change!</b>
*
* #return void
*/
function regenerate_id()
{
// saves the old session's id
$oldSessionID = session_id();
// regenerates the id
// this function will create a new session, with a new id and containing the data from the old session
// but will not delete the old session
session_regenerate_id();
// because the session_regenerate_id() function does not delete the old session,
// we have to delete it manually
$this->_destroy($oldSessionID);
}
/**
* Add or change flashdata, only available
* until the next request
*
* #access public
* #param mixed
* #param string
* #return void
*/
function set_flashdata($newdata = array(), $newval = '')
{
if (is_string($newdata))
{
$newdata = array($newdata => $newval);
}
if (count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
$flashdata_key = $this->flashdata_key.':new:'.$key;
$this->set_userdata($flashdata_key, $val);
}
}
}
// ------------------------------------------------------------------------
/**
* Keeps existing flashdata available to next request.
*
* #access public
* #param string
* #return void
*/
function keep_flashdata($key)
{
// 'old' flashdata gets removed. Here we mark all
// flashdata as 'new' to preserve it from _flashdata_sweep()
// Note the function will return FALSE if the $key
// provided cannot be found
$old_flashdata_key = $this->flashdata_key.':old:'.$key;
$value = $this->userdata($old_flashdata_key);
$new_flashdata_key = $this->flashdata_key.':new:'.$key;
$this->set_userdata($new_flashdata_key, $value);
}
// ------------------------------------------------------------------------
/**
* Fetch a specific flashdata item from the session array
*
* #access public
* #param string
* #return string
*/
function flashdata($key)
{
$flashdata_key = $this->flashdata_key.':old:'.$key;
return $this->userdata($flashdata_key);
}
// ------------------------------------------------------------------------
/**
* Identifies flashdata as 'old' for removal
* when _flashdata_sweep() runs.
*
* #access private
* #return void
*/
function _flashdata_mark()
{
$userdata = $this->all_userdata();
foreach ($userdata as $name => $value)
{
$parts = explode(':new:', $name);
if (is_array($parts) && count($parts) === 2)
{
$new_name = $this->flashdata_key.':old:'.$parts[1];
$this->set_userdata($new_name, $value);
$this->unset_userdata($name);
}
}
}
// ------------------------------------------------------------------------
/**
* Removes all flashdata marked as 'old'
*
* #access private
* #return void
*/
function _flashdata_sweep()
{
$userdata = $this->all_userdata();
foreach($userdata as $key => $value)
{
if (strpos($key, ':old:'))
{
$this->unset_userdata($key);
}
}
}
/**
* Get the number of online users
*
* #return integer number of users currently online
*/
function get_users_online()
{
// counts the rows from the database
$query = $this->CI->db->query("SELECT COUNT(session_id) as count FROM ".$this->tableName);
$result = $query->row();
// return the number of found rows
return $result->count;
}
/**
* Generates key as protection against Session Hijacking & Fixation.
* #access private
* #return string
*/
function _generate_fingerprint()
{
//-- We don't use the ip-adress, because this is a subject to change in most cases (proxies etc.)
$list = array('HTTP_ACCEPT_CHARSET',
'HTTP_ACCEPT_ENCODING',
'HTTP_ACCEPT_LANGUAGE',
'HTTP_USER_AGENT');
$key = array($this->securityCode);
foreach($list as $item)
{
$key[] = $this->CI->input->server($item);
}
return md5(implode("\0", $key));
}
/**
* Custom open() function
*
* #access private
*/
function _open($save_path, $session_name)
{
return(true);
}
/**
* Custom close() function
*
* #access private
*/
function _close()
{
return(true);
}
/**
* Custom read() function
*
* #access private
*/
function _read($session_id)
{
// reads session data associated with the session id
// but only
// - if the fingerprint is the same as the one who had previously written to this session AND
// - if session has not expired
$result = $this->CI->db->query("SELECT session_data ".
"FROM ".$this->tableName." ".
"WHERE session_id = ".$this->CI->db->escape($session_id)." ".
"AND fingerprint = ".$this->CI->db->escape($this->_generate_fingerprint())." ".
"AND session_expire > '".time()."' LIMIT 1");
// if anything was found
if($result->num_rows() > 0)
{
// return found data
$fields = $result->row();
// Unserialization - PHP handles this automatically
return $fields->session_data;
}
// if there was an error return an empty string - this HAS to be an empty string
return("");
}
/**
* Custom write() function
*
* #access private
*/
function _write($session_id, $session_data)
{
// insert OR update session's data - this is how it works:
// first it tries to insert a new row in the database BUT if session_id is already in the database then just
// update session_data and session_expire for that specific session_id
// read more here http://dev.mysql.com/doc/refman/4.1/en/insert-on-duplicate.html
$result = $this->CI->db->query(
"INSERT INTO ".$this->tableName." (".
"session_id,".
"fingerprint,".
"session_data,".
"session_expire".
") VALUES (".
$this->CI->db->escape($session_id).",".
$this->CI->db->escape($this->_generate_fingerprint()).",".
$this->CI->db->escape($session_data).",".
$this->CI->db->escape(time() + $this->sessionLifetime).
")".
"ON DUPLICATE KEY UPDATE ".
"session_data = ".$this->CI->db->escape($session_data).",".
"session_expire = ".$this->CI->db->escape(time() + $this->sessionLifetime));
// note that after this type of queries, mysql_affected_rows() returns
// - 1 if the row was inserted
// - 2 if the row was updated
switch($this->CI->db->affected_rows())
{
// if the row was inserted
case 1:
return("");
break;
// if the row was updated
case 2:
return(true);
break;
// if something went wrong, return false
default:
return(false);
break;
}
}
/**
* Custom destroy() function
*
* #access private
*/
function _destroy($session_id)
{
// deletes the current session id from the database
$result = $this->CI->db->query("DELETE FROM ".$this->tableName." ".
"WHERE session_id = ".$this->CI->db->escape($session_id));
// if anything happened
if($this->CI->db->affected_rows())
{
return(true);
}
// if something went wrong, return false
return(false);
}
/**
* Custom gc() function (garbage collector)
*
* #access private
*/
function _gc($maxlifetime)
{
// it deletes expired sessions from database
$result = $this->CI->db->query("DELETE FROM ".$this->tableName." ".
"WHERE session_expire < ".$this->CI->db->escape(time() - $maxlifetime));
}
}
?>
cheers!
3 years after, a better solution, out of the box.
I've found this on MIT license: https://github.com/kirilkirkov/Shopping-Cart-Solution-CodeIgniter
Using CI3, not using CI cart class, back-end, templates, payments, languages etc. Excellent work!

Zend check if view exist - class does not work

I have found this class:
https://github.com/lloydwatkin/Demos/blob/master/zendframework/renderifexists/RenderIfExists.php
The code looks like this:
<?php
/**
* View helper to render a view file if it exists
*
* #author Lloyd Watkin
* #since 12/12/2010
* #package Pro
* #subpackage View
*/
/**
* View helper to render a view file if it exists
*
* #author Lloyd Watkin
* #since 12/12/2010
* #package Pro
* #subpackage View
*/
class Pro_View_Helper_RenderIfExists
extends Zend_View_Helper_Abstract
{
/**
* Errors
*
* #var string
*/
const INVALID_FILE = 'Invalid file parameter';
/**
* Holds file name for processing
*
* #var string
*/
protected $_file;
/**
* Takes a products options array and converts to a formatted string
*
* #param string $file
* #return string
*/
public function renderIfExists($file)
{
if (!is_string($file) || empty($file)) {
throw new Zend_View_Exception(self::INVALID_FILE);
}
$this->_file = $file;
if (false === $this->_fileExists()) {
return '';
}
return $this->view->render($file);
}
/**
* Check to see if a view script exists
*
* #return boolean
*/
protected function _fileExists()
{
$paths = $this->view->getScriptPaths();
foreach ($paths as $path) {
if (file_exists($path . $this->_file)) {
return true;
}
}
return false;
}
}
I want to check if a view exists; If it does: Show it.
I have placed the file in my /library/. When I call $this->renderIfExists('info-box.phtml'); from the controller I get this error:
Message: Method "renderIfExists" does not exist and was not trapped in __call()
How can I fix this?
Thanks in advance!
to call a view helper from the controller, you should use:
$this->view->renderIfExists()
bit late to this, but the code you've got above is something I wrote. Have you registered the helper path, if w would the framework know where to load the file?

Resources