How to pass parameters to a class constructor - not an array - php

I read some other posts here on stackoverflow about passing parms to a class library (for example, How to pass multiple parameters to a library in CodeIgniter?) and I also read the user manual under the libraries section.
What I'm wondering is if it's possible to pass parameters as individual variables and not as an array?
My class - which I want to use outside of my codeigniter solution- look like this:
<?php
class ABC
{
private $_hostname;
private $_password;
private $_username;
private $_connection;
private $_data;
private $_timeout;
private $_prompt;
public function __construct($hostname, $password, $username = "", $timeout = 10)
{
set_include_path(get_include_path() . PATH_SEPARATOR . '/var/www/phpseclib');
include('Net/SSH2.php');
$this->_hostname = $hostname;
$this->_password = $password;
$this->_username = $username;
} // __construct
public function connect()
{
}
public function dosomething()
{
}
I know I can do something like :
$params = array('_hostname' => $ip, '_password' => 'password', '_username' => '');
$this->load->library($classname,$params );
But I do not want to use arrays because this class will be reused by non CI solutions.
I've tried reverting to using a standard include() statement. So the code looks like:
set_include_path(get_include_path() . PATH_SEPARATOR . 'var/www/myCIapp/application/libraries');
include_once('libraries/'.$classname.'.php');
But it's complaining saying that it cannot find the include file. The specific message is:
A PHP Error was encountered
Severity: Warning
Message: include_once() [function.include]: Failed opening
'libraries/HP5406_ssh.php' for inclusion
(include_path='.:/usr/share/php:/usr/share/pear:var/www/myCIapp/application/libraries/')
Filename: models/ss_model.php
Line Number: 88
Any suggestions would be appreciated. Thanks for reading...

A simple way of doing your include could be dome using the CI APPPATH CONSTANT:
include_once(APPPATH.'libraries/'.$classname.'.php';
This CONSTANT is set in the index.php by CodeIgniter so you know it'll always be pointing to your Application directory.

the solution to the include not working is to change the include statement to look like:
include_once dirname(__FILE__) . '/../libraries/'.$classname.'.php';
I was assuming that it would automatically start with the location of the current file. But that's not true.
The above line will force it to start from the location of the current file.

Related

PHP - Call class function from another class

I am developing an app where I need to log the proccess.
So I was loggin from main.php and now I need to log from another class (class_TestingLog.php)
Next code is how I am trying. Could you tell me what I am doing wrong?
Thank you in advance.
main.php
[...]
#Logging class
include_once("./classes/class_log.php");
$Class_Log = New Class_Log();
#TestingLog Class
include_once("./classes/class_testingLog.php");
$Class_TestingLog = New Class_TestingLog();
[...]
$Class_Log->FreeLog("Test log");
$Class_TestingLog->AnyFuncion();`
[...]
class_log.php
[...]
public function FreeLog($text)
{
// echo $text . "\n"; #mistake
$this->outputText .= text; #correct one
}
[...]
class_testingLog.php
private $Class_Log = '';
[...]
public function __construct()
{
#Requires
require_once("./classes/class_log.php");
$this->Class_Log = New Class_Log();
}
public function AnyFuncion()
{
var_dump($this); #From real file
$this->Class_Log->FreeLog("Test log from another classs");
}
[...]
Browser output
Test log
Browser output expected
Test log
Test log from another classs
===========================================================================
EDIT
I made an error copying FreeLog();
It stores the parameter string value into a private variable instead echo the variable.
You require_once statement inside __construct for Class_TestingLog is invalid and unnecessary. As both files are in the same directory it should be "class_log.php" not "./classes/class_log.php". There is no need for it anyway, as when you include them both in main.php it is loaded already. So try it without the require_once.
EDIT: As discussed in chat do it like this:
in main.php:
$Class_TestingLog = New Class_TestingLog($Class_Log);
in class_testingLog.php:
public function __construct($ClassLog)
{
$this->Class_Log = $ClassLog;
}
This will use the same instance inside the Class_TestingLog class as on the main.php.

Variable Variables in PHP from required / included files

I am writing a MVC Framework (for the purpose of learning and discovery as opposed to actually intending to use it) and I have came across a slight problem.
I have a config.php file:
$route['default'] = 'home';
$db['host'] = 'localhost';
$db['name'] = 'db-name';
$db['user'] = 'user-name';
$db['pass'] = 'user-pass';
$enc_key = 'enc_key'
I load these via a static method in my boot class:
public static function getConfig($type) {
/**
* static getConfig method gets configuration data from the config file
*
* #param string $type - variable to return from the config file.
* #return string|bool|array - the specified element from the config file, or FALSE on failure
*/
if (require_once \BASE . 'config.php') {
if (isset(${$type})) {
return ${$type};
} else {
throw new \Exception("Variable '{$type}' is undefined in " . \BASE . "config.php");
return FALSE;
}
} else {
throw new \Exception("Can not load config file at: " . \BASE . 'config.php');
return FALSE;
}
}
and then load the route like so:
public function routeURI($uri) {
...
$route = $this::getConfig('route');
...
}
which catches the exception:
"Variable 'route' is undefined in skeleton/config.php"
now, it works fine if I make the config.php file like so
$config['route']['default'] = 'home'
...
and change the two lines in the method like so:
if (isset($config[$type])) {
return $config[$type];
I have also tried using $$type instead of ${$type} with the same problem.
Is there something I am overlooking?
As written, this function can be called only once, because it uses require_once and on subsequent calls you won't bring in the local variables defined in config.php anymore. I suspect you are getting this error on your second call to getConfig().

php Fatal error: Cannot redeclare class AppMailCore in /appmail.core.php on line 10

I'm getting this error when I run the script
php Fatal error: Cannot redeclare class AppMailCore in /appmail.core.php on line 10
I need to make loop that will also use some variables from a class file . The code from main.php looks like this :
$iesc = 1;
while($iesc less than 5)
{
include('includes/appmail.core.php');
---
I used "less than " in the code above 'cause I don't know to unescape "<" symbold within the pre markup .
I understand that I'm not allowed to re-delcare the class but I don't know how to make the class variables run through the loop .
appmail.core.php looks like this
require_once('appmail.config.php');
require_once('helpers'.DIRECTORY_SEPARATOR.'appmail.rest.php');
class AppMailCore
{
var $AppMailRest;
var $api_key;
var $url;
/**
* Initialises AppMailCore. Optionally provide runtime api key and url.
*/
function AppMailCore($api_key = APPMAIL_API_KEY, $url = APPMAIL_URL) {
$this->url = $url;
$this->api_key = $api_key;
$this->AppMailRest = new AppMailRest($this->url);
}
/**
* Asynchronously sends an email using Google App Engine
*
* Params are fairly self explanatory. However, note that the "from" address must be a registered email with
* your Google App Engine account.
*/
function send($to, $from, $subject, $plain, $html) {
$api_key = $this->api_key;
$status = $this->AppMailRest->post('send', compact('api_key','to','from','subject','plain','html'));
return $status;
}
}
the appmail.config.php loooks like this
$app1DB = new mysqli("localhost", "root", "", "ast");
$app1RSP = $app1DB->query("SELECT app_id FROM Application WHERE emails_sent fetch_assoc();
$app_id = $app1Object['app_id'];
define('APPMAIL_API_KEY', 'JLQ7P5SnTPq7AJvLnUysJmXSeXTrhgaJ');
define('APPMAIL_URL', "http://$app_id.appspot.com/");
$app1RSP->free();
$app1DB->close();
Basically I need to get variable APPMAIL_URL/$app_id in the class on each loop run.
Why aren't you doing the include before the loop ?
Another tip: use include_once ?
Third tip: include directly appmail.config.php if you need a constant from it, not appmail.core.php ?
EDIT
Basically I need to get variable
APPMAIL_URL/$app_id in the class on
each loop run.
If its value is supposed to change through the script execution (as I just saw), then you shouldn't define it as a constant.

Getting WordPress database name/username/password with PHP

I'm writing a WordPress plug-in and need to read the database name, username, and password (In order to do a sql dump). Is this possible?
Thanks-
Yes, they are defined in wp-config.php
Database Name: DB_NAME
Database User: DB_USER
Database password: DB_PASSWORD
Database Host: DB_HOST
They are define. See you wp-config.php in the root directory of Wordpress
Wordpress has some fairly goofy stuff going on throughout its OO code, this isn't the first one I've encountered as we dig deeper into the internals with each successive project at Moxune. See WP_User::__set doesn't persist custom fields as it claims.
The goofiness I refer to here of course is that something like the table prefix, aka wpdb::prefix is a public member variable, however things like dbname, dbpassword, and dbhost are protected and there are no public accessor methods.
I'm sure one of the Wordpress core devs will try to argue some rationale for it, but in the meantime may as well use some good 'ol OO to cope. My suggestion, a decorator.
class SaneDb
{
private $_oDb;
public function __construct(wpdb $oDb)
{
$this->_oDb = $oDb;
}
public function __get($sField)
{
if($sField != '_oDb')
return $this->_oDb->$sField;
}
public function __set($sField, $mValue)
{
if($sField != '_oDb')
$this->_oDb->$sField = $mValue;
}
public function __call($sMethod, array $aArgs)
{
return call_user_func_array(array($this->_oDb, $sMethod), $aArgs);
}
public function getDbName() { return $this->_oDb->dbname; }
public function getDbPass() { return $this->_oDb->dbpassword; }
public function getDbHost() { return $this->_oDb->dbhost; }
}
Then atop your plugin code (functions.php) setup a global in similar vein to wpdb.
global $sanedb;
$sanedb = new SaneDb($wpdb);
From there, just use $sanedb within your plugin instead of $wpdb.
Lastly, getting ahold of the database name et al.
$sanedb->getDbName();
This is super simple now. You can create a PHP file and use the following code.
$path = $_SERVER['DOCUMENT_ROOT'];
include_once $path . '/wp-config.php';
include_once $path . '/wp-load.php';
include_once $path . '/wp-includes/wp-db.php';
include_once $path . '/wp-includes/pluggable.php';
// We need the WordPress Database Credentials
global $wpdb;
$user = $wpdb->dbuser;
$pass = $wpdb->dbpassword;
$name = $wpdb->dbname;
If you need other data just do a print_r on the wpdb variable and you'll see everything inside of there.

PHP global, nested/inherited autoload

PHP 5.3.3-pl1-gentoo (cli) (built: Aug
17 2010 18:37:41)
Hi all, I use a simple autoloader in my project's main file (index.php):
require_once("./config.php");
require_once("./app.php");
require_once("./../shared/SqlTool.php");
function __autoload($className) {
$fn = 'file-not-exists-for-{$className}';
if (file_exists("./specific/php/{$className}.php")) { $fn = "./specific/php/{$className}.php"; } else
{ $fn = "./../shared/{$className}.php";}
require_once($fn);
}
$sql = new SqlHD(); // class SqlHD, in ./specific/php/SqlHD.php extends SqlTool
$web = new HTMLForm($sql); // class HTMLForm in HTMLForm.php
$app = new App($sql, $web); // class App in App.php
$app->Main();
The problem: without that require_once("./../shared/SqlTool.php");, script can't execute SqlHD.php, because it can't find SqlTool.php by itself, and for some reason it doesn't uses autoload routine defined in main file.
I tried this:
spl_autoload_register(__NAMESPACE__ .'\Test::load');
class Test {
static public function load($className){
$fn = 'file-not-exists-for-{$className}';
if (file_exists("./specific/php/{$className}.php")) { $fn = "./specific/php/{$className}.php"; } else
{ $fn = "./../shared/{$className}.php}";}
echo realpath($fn);//"$curRealDir Filename $fn\n";
echo "\n";
require_once($fn);
}
}
Well,
PHP Warning:
require_once(./../shared/SqlTool.php}):
failed to open stream: No such file or
directory in
/home/beep/work/php/hauthd/index.php
on line 20 PHP Fatal error:
require_once(): Failed opening
required './../shared/SqlTool.php}'
(include_path='.:/usr/share/php5:/usr/share/php')
in
/home/beep/work/php/hauthd/index.php
on line 20
So it doesn't reacts to any request from extended class.
Last second idea: put spl_autoload_register to each file. But cannot put it to "extends" directive itself!
P.S. May rewrite SqlTool.php using Factory pattern so it would automatically return an instance of project-specifc class, but it seems to be not a best way, or it is..?
If SqlHD extends SqlTool, then your __autoload() function should include this automatically.
Note you have an extra '}' in your filename which is probably messing this up. (Which you have also copy 'n' pasted into your 2nd code snippet.)
{ $fn = "./../shared/{$className}.php}";}
As an aside, I think you only need to require() inside your __autoload() function, rather than require_once(), since your __autoload() function is only called if it has not already been loaded.
[Edit: removed incorrect relative path suggestion - w3d spotted the real problem. Leaving the rest here just for info]
Also you can change the require_once in the autoload function to just require - by definition the function will only run if the class has not already been included.
You could greatly simplify your autoload by utilising the include path, as then PHP would check the different locations for you. E.g. something like this:
set_include_path(
realpath('./specific/php') . PATH_SEPARATOR .
realpath('./../shared') . PATH_SEPARATOR .
get_include_path()
);
function __autoload($className) {
require "$className.php";
}

Categories