Custom Libraries in code igniter and config files? - php

I have a library in code igniter that looks like class MyClass($options = array())
The file is Myclass.php
I have a file (config/Myclass.php) that looks like
$Myclass = array(
'something' => 'value',
'another' => 'value'
);
Which I thought should pass the $Myclass array in when I initialize my class, but apparently not?
What do I need to do to fix it?

AH I found the answer,
The array inside your config file must be called $config.
The name of the file must also be a lower case representation of the library file name.
e.g
LIB FILE: Somelibrary.php
LIB CONTENTS: class Somelibrary($options = array()){...
CONF FILE: somelibrary.php
CONF CONTENTS: $config = array('something' => 'value');

The way this usually works is that you pass in an array of options you wish to override, or pass in nothing to use the defaults.
var myObject = new MyClass(); // default settings
var myObject = new MyClass(array('something' => 'value2')); // override only "something"
Honestly, I wouldn't create your own file in config without a good reason; instead, just put the defaults in your class definition, and then override in your constructor:
class MyClass {
var $default_options = array(
'something' => 'value',
'another' => 'value',
);
var $options = array();
function MyClass($override_options = array())
{
$this->options = array_merge($this->default_options, $override_options);
// your code here...
}
}

Fast-forward to 2013, someone is still having problems with this. So my situation was the same but slightly different, so I thought I'd try to save someone else some time.
I was naming my config file after my extended class, that was wrong. The Config file should always be form_validation.php, (this is because eventually it is handed to the CI_Form_validation class and that's what it expects)
Thanks to the folks who answered this question above, I realized that I had to pass the config to the parent class and using codeigniter v2.1.3 I did it as follows:
public function __construct( $config = array() )
{
parent::__construct($config);
}

Related

How to use a global constant instead of a class constant in PHP version 5.6

I'm using Monolog to create my app's logging system. In the core app file, after I create a new Monolog object, I need to select the log level that I want to print in the log file. I want to use a global constant LOG_LEVEL which could be 'DEBUG', 'INFO', etc. I need the Monolog class to treat its value as a class constant.
// content of config.php
// Here I declare the constants in a separate file called 'config.php'
define("LOG_FILE", "patch/to/my/log.log");
define("LOG_LEVEL", "ERROR");
// content of app.php
require 'config.php';
require 'vendor/autoload.php';
$container['logger'] = function($c) {
$logger = new \Monolog\Logger('logger');
error_log('log level ' . LOG_LEVEL); // prints 'log level ERROR'
$fileHandler = new \Monolog\Handler\StreamHandler(LOG_FILE, $logger::LOG_LEVEL); // here I get the error 'Undefined class constant LOG_LEVEL'
//the normal syntax would be '$logger::ERROR' in this case and that works fine
$logger->pushHandler($fileHandler);
return $logger;
};
I need the 'LOG_LEVEL' constant to be used as 'ERROR' by the monolog class, not as 'LOG_LEVEL'. What am I doing wrong here, been searching an answer for hours now without any luck.
You are now doing $logger::LOG_LEVEL, which is taking the 'LOG_LEVEL' out of the class whichever $logger is (in this case a \Monolog\Logger). That doesn't have a static variable named LOG_LEVEL, thus you get the undefined.
You have just have 'LOG_LEVEL' defined, out of any class, so:
$fileHandler = new \Monolog\Handler\StreamHandler(LOG_FILE, LOG_LEVEL);
Fancy solution:
You could do a static class and include that in your main page:
Class CONFIG {
public static $LOG_LEVEL = 'default Value';
}
// Then you can use this anywhere:
CONFIG::$LOG_LEVEL
$fileHandler = new \Monolog\Handler\StreamHandler(LOG_FILE, CONFIG::$LOG_LEVEL);
The advantage of this is having only one file for configs, not scattered across all kinds of files, which'll become very annoying very fast.
Make a static class and include that...
class GLOBALCONF{
public static $VALUE= 'Something in here';
}
// Use it where you want
GLOBALCONF::$VALUE
You're making this more complicated than it needs to be. Monolog has a function to convert an error level as as string to its own internal value. Just change your code to this:
$fileHandler = new \Monolog\Handler\StreamHandler(LOG_FILE, $logger::toMonologLevel(LOG_LEVEL));
You can also use Logger::getLevels() like the following:
$log_level = $logger->getLevels()[LOG_LEVEL];
$fileHandler = new ...StreamHandler(LOG_FILE, $log_level);

How to write and use config files in Zend Framework 2

Hi,
In Zend Framwork 1, I used to have an application\configs\appsettings.xml, where I used to store params and values like hostnames for Rest API URLs, debug settings and other application specific settings for dev, test and prod environments. This registry was available to me across all controllers and models and was created in index.php
$applicationEnvironment = 'development';
$config = new Zend_Config_Xml( APPLICATION_PATH . '/configs/appsettings.xml',
$applicationEnvironment, true );
Zend_Registry::set( 'config', $config );
How do I achieve similar thing in Zend Framework 2?
Thanks
There is no such thing as a Registry in ZF2 because it is kind of an anti pattern. It's just a fancy substitution for global variables, which can cause all sort of unwanted side effects in your application.
In ZF2 you have the serviceManager and this allow to cleanly inject all your dependencies into your controllers/models/services. All config files in the config/autoload directory are automaticaly merged into one single array by ZF2 and you can retrieve this from the service manager using $serviceLocator->get('Config'). Whenever you need to use configuration in your controller just create a serviceFactory and inject the config.
class FooController
{
protected $config;
public __construct($config)
{
$this->config = $config;
}
public barAction()
{
//use $this->config
}
}
class Module
{
public function getControllerConfig()
{
return array(
'factories' => array(
'fooController' => function(ControllerManager $cm)
{
$sm = $cm->getServiceLocator();
$config = $sm->get('Config');
$controller = new FooController($config);
return $controller;
},
),
);
}
}
For sake of simplicity the factory above is defined as a closure, but I'd suggest to create a seperate factory class. There are many resources which explain how to do that.
In this example we are injecting the complete configuration, but depending on your use case it will generally be better to only inject the config keys you need.
Alternatively you can wrap certain config values into a dedicated config object with explicit getters and setters and inject this into your controller. Zend\StdLib\AbstractOptions can help you.
If you wish to work with config files and you dont have access to the Service Manager or you wish to write content to it, you can use Zend\Config
To read from, you can do something like:
$config = new Config(include 'config/autoload/my_amazing_config.global.php');
$details = $config->get('array_key')->get(sub_key)->toArray();
To write to, you can do:
// Create the config object
$config = new Zend\Config\Config(array(), true);
$config->production = array();
$config->production->webhost = 'www.example.com';
$config->production->database = array();
$config->production->database->params = array();
$config->production->database->params->host = 'localhost';
$config->production->database->params->username = 'production';
$config->production->database->params->password = 'secret';
$config->production->database->params->dbname = 'dbproduction';
$writer = new Zend\Config\Writer\Xml();
echo $writer->toString($config);
The class support ini, xml, phpArray, json, yaml
You can read more at:
http://framework.zend.com/manual/2.2/en/modules/zend.config.introduction.html

yii - how to create a completely independant extension using nusoap 0.9.5 in yii 1.1.13

SOLVED Thanks to #JPR and tuned-up thanks to #PeterM
/* The only dependance is when */ class NuSoap extends CApplicationComponent
v-Below, the initial question -v
I would like to know how to create a basic extenstion in yii 1.1.13 using nusoap 0.9.5?
My simple code looks like this :
<?php
require("libs/nusoap-0.9.5/lib/nusoap.php");
// namespace
$ns = "https://my-namespace-site";
// client
$client = new soapclient('https://ip-to-webservice-server');
// header
$headers = "<credentials><ns1:username xmlns:ns1=\"$ns\">username</ns1:username>
<ns2:password xmlns:ns2=\"$ns\">password</ns2:password></credentials>";
$client->setHeaders($headers);
// searching
$params = array(
'local_user_array' => array(
'limit' => 10
)
);
$result = $client->call('local_users_search', $params, $ns );
if( $client->getError() ) {
echo $client->getError();
}
else {
foreach( $result['data'] as $offer ) {
echo "<div>".$offer['firstname']."</div>";
}
}
?>
My code works perfectly. Now, what coud I do to use $result in yii to be able to show results in a view?
The best answer will be a concrete example with file structure and code plus meaningful explanations.
Any help would be greatly appreciated. Thanks for your help in advance. I'm looking forward to it ;-)
PS: please do not reference any links to yiiframework site because it doesn't help much as I also know how to search.
Make a class that extends from CApplicationComponent.
class NuSoap extends CApplicationComponent
{
protected $params = array();
protected $client, $ns;
public function init() {
require("libs/nusoap-0.9.5/lib/nusoap.php");
$this->client = new soapclient('https://ip-to-webservice-server');
$this->ns = "https://my-namespace-site";
}
public function getResults() {
$results = $this->client->call(
'local_users_search',
$this->params,
$this->ns
);
return $results;
}
public function setParams(array $params) {
$this->params = $params;
}
// whatever other methods you need for it to work
}
Then in your main config file, under the components array:
array(
'nuSoap' => array(
'class' => 'application.components.NuSoap' // name your class NuSoap.php
)
......
)
Make sure the application/components or application/extensions directory is imported in the main.php config file as well. Put your class file in NuSoap.php in the application/components or applcation/extensions directory.
You can now refer to your component anywhere in your Yii app:
Yii::app()->nuSoap->setParams($params);
$results = Yii::app()->nuSoap->getResults();
This should be plenty to get you started in the right direction. The Yii documentation would be very helpful in understanding how application components work, but since you don't want to read it you'll just have to guess on some things. If you want to use Yii it makes absolutely no sense to avoid reading the documentation.

Unable to access variable from included file

As the title says there is a problem accessing variable (associative array) inside class from included file. Here is the source code both class and include file:
require("applications/cw_database.php");
require("config/dbConfig.php");
require("config/appConfig.php");
class APP_ASSESMENTS
{
private $dbObj;
private $DisplayOutput = "";
public function __construct($PageParams)
{
try
{
$dbObj = new CW_DB($dbConfig['hostname'],$dbConfig['username'],$dbConfig['password'],$dbConfig['name'],$dbConfig['port']);
} catch (Exception $e) {
throw new ErrorException($e);
}
}
...
The other part has nothing to do with $dbConfig.
Also this is the included file (config/dbConfig.php):
/*
Testing configuration for MySQL database
*/
$dbConfig['username'] = "phpcoursework"; // changed on demand
$dbConfig['password'] = "phpcoursework"; // changed on demand
$dbConfig['hostname'] = "localhost"; // changed on demand
$dbConfig['name'] = "students"; // changed on demand
$dbConfig['port'] = 3306; // default for MySQL
First, $dbObj will not automatically assume class member scope, it will create a local copy of CW_DB and discard it when __construct returns. You need to explicitly reference the property;
$this->dbObj = ...
Anyway, global state using global as suggested by others will "work", but if you're using OOP practices you're best not to do that. You can actually return from an include(), so an option would be to do the following:
// your config file dbConfig.php
return array(
'username' => "phpcoursework",
'password' => "phpcoursework",
'hostname' => "localhost",
'name' => "students",
'port' => 3306,
);
And inject it into the object, via constructor or method (here's constructor)
class APP_ASSESMENTS
{
private $dbObj;
public function __construct($dbConfig, $PageParams)
{
$dbObj = new CW_DB($dbConfig['hostname'], $dbConfig['username'],
$dbConfig['password'], $dbConfig['name'], $dbConfig['port']);
// ...
}
}
// include() here, will actually return the array from the config file
$appAssesments = new \APP_ASSESMENTS(include('dbConfig.php'), $PageParams);
It would be recommended that you go another level up: instead, inject the database object itself, taking the dependency out of your APP_ASSESSMENTS class.
(Also, PascalCase is the typical convention of class naming, such as AppAssessments and CwDb)
$dbObj = new CwDb(include('dbConfig.php'));
$appAssessments = new AppAssessments($dbObj, $etc, $etc);
This simple change allows you to remove the dependency from AppAssessments on CwDb. That way, if you extend CwDb for some reason, you can just pass in an instance of the extended class without having to change any code in AppAssessments
You can change the AppAssessments constructor like so:
public function __construct(CwDb $db, $etc, $etc){
$this->db = $db;
// ...
}
This takes advantage of PHPs (limited, albeit still useful) type-hinting, ensuring the first argument is always of the correct type.
This plays into part of the open/closed principle: classes should be open to extension but closed for modification.
Includes are used in the scope of access. So, to access the variables you need to include the files within your class. As earlier mentioned global will let you access variables from another scope too. But global should be used with caution! See the documentation.
See the manual for more information.
Edit: I need to make it clear that globals are never a good alternative for handling these kind of critical variables..
public function __construct($PageParams){
global $dbConfig;
try{
$dbObj = new CW_DB($dbConfig['hostname'],$dbConfig['username'],$dbConfig['password'],$dbConfig['name'],$dbC onfig['port']);
} catch (Exception $e) {
throw new ErrorException($e);
}
}
or you could use $GLOBALS['dbConfig'].

Proper way to use a config file?

I just started using a PHP framework, Kohana (V2.3.4) and I am trying to set up a config file for each of my controllers.
I never used a framework before, so obviously Kohana is new to me. I was wondering how I should set up my controllers to read my config file.
For example, I have an article controller and a config file for that controller. I have 3 ways of loading config settings
// config/article.php
$config = array(
'display_limit' => 25, // limit of articles to list
'comment_display_limit' => 20, // limit of comments to list for each article
// other things
);
Should I
A) Load everything into an array of settings
// set a config array
class article_controller extends controller{
public $config = array();
function __construct(){
$this->config = Kohana::config('article');
}
}
B) Load and set each setting as its own property
// set each config as a property
class article_controller extends controller{
public $display_limit;
public $comment_display_limit;
function __construct(){
$config = Kohana::config('article');
foreach ($config as $key => $value){
$this->$key = $value;
}
}
}
C) Load each setting only when needed
// load config settings only when needed
class article_controller extends controller{
function __construct(){}
// list all articles
function show_all(){
$display_limit = Kohana::config('article.display_limit');
}
// list article, with all comments
function show($id = 0){
$comment_display)limit = Kohana::config('article.comment_display_limit');
}
}
Note: Kohana::config() returns an array of items.
Thanks
If you are reading a group of configuration items for a controller, store them in class member ($this->config), if you are reading a single configuration item; read it individually.
I think first method (A) should be fine, it has lesser code and serves the purpose fine.
If you have site wide stuff that you want access to from "anywhere", another way of doing it may be to put something like:
Kohana::$config->attach(new Kohana_Config_File('global'));
in bootstrap.php. Then create global.php in the application/config directory with something like:
return (array ('MyFirstVar' => 'Is One',
'MySecondVar' => 'Is Two'));
And then when you need it from your code:
Kohana::config ('global.MyFirstVar');
But I suppose all of this comes down to where and how you want to use it.

Categories