PHP - Dynamic Namespaced Class Instantiation
So I'm pounding away at some of the new 5.3 features to try and get a grasp on setting up a custom MVC. spl_autoload with namespaces is frikkin awesome, however im trying to make life easy by being able to drop a class file in an "objects" folder that holds all the models for the app and have the controller parse out the get request for the proper model call and dynamically create the object. Example:
url = www.example.com/?auth controller parses $_GET and see's you are requesting the auth module. Now I'm having an issue instantiating a variable that has a namespace\class inside it: Code: [Select] $namespace = 'objects\\'; $clean['object'] = $namespace.key($clean['get']); $this->object = new $clean['object']; Logfile: PHP Fatal error: spl_autoload(): Class objects\\testobject could not be loaded... OK, its trying to escape the backslash? Maybe some trickery is needed? Code: [Select] $clean['object'] = $namespace.chr(92).key($clean['get']); NOPE, still the same error... Any cluepons? Similar TutorialsI'm trying to implement a library which was written for PSR-0 compliant autoloading in my joomla project. However joomla 2.5 does not support PSR-0 autoloading so I figured that I would have to write my own implementation.
Since I want to use my classes across my entire joomla installation I decided to write a plugin which registers the classes onAfterInitialise() but this is where it goes wrong: it overrides joomla's autoloading methods.
The library i'm trying to implement is located at libraries/Zoho/CRM/ZohoClient.php with several subfolders. Everything is namespaced with accordance to PSR-0 so starting with: \Zoho\CRM.
How do I register the classes in such a way that I can use them globally across joomla? This is my implementation:
public function onAfterInitialise() { spl_autoload_register(function ($className) { $className = ltrim($className, '\\'); $fileName = ''; $namespace = ''; if ($lastNsPos = strripos($className, '\\')) { $namespace = substr($className, 0, $lastNsPos); $className = substr($className, $lastNsPos + 1); $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; } $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; require $fileName; }); }This obviously wont work because it overrides the joomla autoloading function. I'm running php5.3 (5.4 in 3 months) Hello, I'm new to the forum and I'm looking for advice. I use a bunch of classes in namespaces that are I'm attempting to organize for autoloading. In other words, a class called \Foo\Package\Class is loaded from the file at Foo\Package\Class.php. I'm using spl_autoload for this. (If I were on 5.2 I could be using underscore-delimited pseudo-namespaces just as well; the implementation detail isn't important) Now, I want to have multiple separate apps that use a single common library. Each app also has some classes that are local to it. How should I solve the autoloading problem? I thought of the following approach. Is it any good? Try autoloading from the common class library If it fails, try autoloading from the app's own local library Part 2 of the question: Within my apps, though, there are two types of classes: library ("vendor") classes that are only being used in that particular app so they don't need to be in the shared library, and app-specific classes that are the core of the app (so they, by definition, don't need to be in any shared library). I'd probably like to keep these two separate, so I'd need to add point #3 to the list above: search in the "core" class hierarchy of the local app. This gives 3 separate locations, and the problem is that they negate the advantages namespaces since there can be overlap. In which case one class will override the other during autoloading. So order of the above list would matter. And time would be wasted looking for a class in the first two places if it's more often in the third. A solution I was considering is sticking to just one central library of classes (and dumping all app-local libraries there). Then, the core classes that belong to one app would be under an \AppName namespace. I'm looking forward to some insights from the experts. How do you guys organize your class libraries? I have mysqli object in Database class base: [color=]database class:[/color] class Database { private $dbLink = null; public function __construct() { if (is_null($this->dbLink)) { // load db information to connect $init_array = parse_ini_file("../init.ini.inc", true); $this->dbLink = new mysqli($init_array['database']['host'], $init_array['database']['usr'], $init_array['database']['pwd'], $init_array['database']['db']); if (mysqli_connect_errno()) { $this->dbLink = null; } } } public function __destruct() { $this->dbLink->close(); } } Class derived is Articles where I use object dBLink in base (or parent) class and I can't access to mysqli methods (dbLink member of base class): Articles class: require_once ('./includes/db.inc'); class Articles extends Database{ private $id, .... .... $visible = null; public function __construct() { // Set date as 2009-07-08 07:35:00 $this->lastUpdDate = date('Y-m-d H:i:s'); $this->creationDate = date('Y-m-d H:i:s'); } // Setter .... .... // Getter .... .... public function getArticlesByPosition($numArticles) { if ($result = $this->dbLink->query('SELECT * FROM articles ORDER BY position LIMIT '.$numArticles)) { $i = 0; while ($ret = $result->fetch_array(MYSQLI_ASSOC)) { $arts[$i] = $ret; } $result->close(); return $arts; } } } In my front page php I use article class: include_once('./includes/articles.inc'); $articlesObj = new articles(); $articles = $articlesObj->getArticlesByPosition(1); var_dump($articles); [color=]Error that go out is follow[/color] Notice: Undefined property: Articles::$dbLink in articles.inc on line 89 Fatal error: Call to a member function query() on a non-object in articles.inc on line 89 If I remove constructor on derived class Articles result don't change Please help me Folks, I need help (Php code ) to generate a Dynamic Text on a Base Image. What i want to do is, to make this Image as header on my Site and to make this Header Specific to a Site, i want to Add the Domain Name on the Lower Left of the Image. Got the Idea? Here is the Image link: Quote http://img27.imageshack.us/i/shoppingheader1.jpg/ PHP Variable that holds the Domain name is: $domain All i need the Dynamic PHP Codes that i can put on all my sites to generate this Text on Image (Header) Dynamically... May Anyone Help me with this Please? Cheers Natasha T. I have an existing instance of my class Database, now I want to call that instance in my Session class, how would I go about doing this? If a class has a constructor but also has a static method, if I call the static method does the constructor run so that I can use an output from the constructor in my static method? --Kenoli Ok. I know you can pass the object of a class as an argument. Example: class A { function test() { echo "This is TEST from class A"; } } class B { function __construct( $obj ) { $this->a = $obj; } function test() { $this->a->test(); } } Then you could do: $a = new A(); $b = new B($a); Ok so that's one way i know of. I also thought that you could make a method static, and do this: (assuming class A's test is 'static') class B { function test() { A::test(); } } But that is not working. I'd like to know all possible ways of accomplishing this. Any hints are appreciated. thanks Hi Can you call Class A's methods or properties from Class B's methods? Thanks. Hi, I need to be able to call a class based on variables. E.G. I would normally do: Code: [Select] $action = new pattern1() but i would like to be able to do it dynamicaly: Code: [Select] $patNum = 1; $action = new pattern.$patNum.() Im wondering if that's possible? If so what would the correct syntax be? Many Thanks. Hi all I need to combine these two scripts: Firstly, the following decides which out of the following list is selected based on its value in the mySQL table: <select name="pack_choice"> <option value="Meters / Pack"<?php echo (($result['pack_choice']=="Meters / Pack") ? ' selected="selected"':'') ?>>Meters / Pack (m2)</option> <option value="m3"<?php echo (($result['pack_choice']=="m3") ? ' selected="selected"':'') ?>>Meters / Pack (m3)</option> <option value="Quantity"<?php echo (($result['pack_choice']=="Quantity") ? ' selected="selected"':'') ?>>Quantity</option> </select> Although this works OK, I need it also to show dynamic values like this: select name="category"> <?php $listCategories=mysql_query("SELECT * FROM `product_categories` ORDER BY id ASC"); while($categoryReturned=mysql_fetch_array($listCategories)) { echo "<option value=\"".$categoryReturned['name']."\">".$categoryReturned['name']."</option>"; } ?> </select> I'm not sure if this is possible? Many thanks for your help. Pete I have two classes: ## Admin.php <?php class Admin { public function __construct() { include("Config.php"); } /** * deletes a client * @returns true or false */ function deleteClient($id) { return mysql_query("DELETE FROM usernames WHERE id = '$id'"); } } ?> ## Projects.php <?php class Projects { public function __construct() { include("Config.php"); $this->admin = $admin; $this->dataFolder = $dataFolder; } /** * Deletes a project * @returns true or false */ function deleteProject($id) { $root = $_SERVER['DOCUMENT_ROOT']; $theDir = $root . $this->dataFolder; $sql = mysql_query("SELECT * FROM projectData WHERE proj_id = '$id'"); while ($row = mysql_fetch_array($sql)) { $mainFile = $row['path']; $thumb = $row['thumbnail']; if ($thumb != 'null') { unlink($theDir . "/" . substr($thumb,13)); } unlink($theDir . "/" . substr($mainFile,13)); } $delete = mysql_query("DELETE FROM projectData WHERE proj_id = '$id'"); $getDir = mysql_query("SELECT proj_path FROM projects WHERE id = '$id'"); $res = mysql_fetch_array($getDir); rmdir($theDir . "/" . $res['proj_path']); return mysql_query("DELETE FROM projects WHERE id = '$id'"); } } ?> How can I call deleteProject() from within Admin.php? Hi people! class FirstOne{ public function FunctionOne($FirstInput){ //do stuff and output value return $value1; } } Then:- class SecondOne{ public function FunctionTwo($AnotherInput){ //do stuff and output value return $value2; } } What I want to know is this, if I want to use FunctionOne() in Class SecondOne do I do it like this:- (Assume as I have instantiated the first class using $Test = new FirstOne(); ) class SecondOne{ function SecondedFunction(){ global $Test; return $Test->FunctionOne(); } public function FunctionTwo($AnotherInput){ //do stuff and output value return $value2; } public function FunctionThree(){ //some code here $this->Test->SecondedFunction();<--I think as I can omit the $this-> reference } } My point is: Do I have to do it this way or is there way of having this done through __construct() that would negate the need for a third party function? I have a version working, I just think that it is a little convoluted in the way as I have done it, so I thought I would ask you guys. Any help/advice is appreciated. Cheers Rw Hi all, I have two classes. Registration and Connection. Inside a registration.php I include my header.php, which then includes my connection.php... So all the classes should be declared when the page is loaded. This is my code: registration.php: <?php include ('assets/header.php'); ?> <?php class registration{ public $fields = array("username", "email", "password"); public $data = array(); public $table = "users"; public $dateTime = ""; public $datePos = 0; public $dateEntryName = "date"; function timeStamp(){ return($this->dateTime = date("Y-m-d H:i:s")); } function insertRow($data, $table){ foreach($this->fields as $key => $value){ mysql_query("INSERT INTO graphs ($this->fields) VALUES ('$data[$key]')"); } mysql_close($connection->connect); } function validateFields(){ $connection = new connection(); $connection->connect(); foreach($this->fields as $key => $value){ array_push($this->data, $_POST[$this->fields[$key]]); } $this->dateTime = $this->timeStamp(); array_unshift($this->data, $this->dateTime); array_unshift($this->fields, $this->dateEntryName); foreach($this->data as $value){ echo "$value"; } $this->insertRow($this->data, $this->table); } } $registration = new registration(); $registration->validateFields(); ?> <?php include ('assets/footer.php'); ?> At this point I cannot find my connection class defined on another included/included page. $connection = new connection(); $connection->connect; config.php (included within header.php) <? class connection{ public $dbname = '**'; public $dbHost = '**'; public $dbUser = '**'; public $dbPass = '**'; public $connect; function connect(){ $this->connect = mysql_connect($this->dbHost, $this->dbUser, $this->dbPass) or die ('Error connecting to mysql'); mysql_select_db($this->dbname, $this->connect); } } ?> Any ideas how to call it properly? How does one go about using one class inside another? For example, building a class that does some series of functions, and uses a db abstraction layer class in the process? I do know how to do this but I am curious about whether or not there is a "preferred" way to do this. I know there are a couple ways to use a class (I'll call Alpha_Class) within another class (I'll class Beta_Class) Let's say we have this simple class (Beta_Class): class beta { function foo(){ } } If I wanted to use the Alpha Class within the Beta Class, I could any number of things. For example: class beta { function foo(){ $this->alpha = new alpha; //$this->alpha->bar(); } } Or you could simply use the $GLOBALS array to store instantiated objects in: $GLOBALS['alpha'] = new alpha; class beta { function foo(){ //GLOBALS['alpha']->bar(); } } You could even declare Alpha_Class as a static class and thus would not need to be instantiated: static class alpha { static function bar(){} } class beta { function foo(){ //alpha::bar(); } } Those are the only ways I can think of right now. Are there any other ways to accomplish this? I was wondering which way is the best in terms of readability and maintainability. I have a class in which I have a function called connection. I am now trying to call this function from another class, but it will not work. It works if I put the code in from the other function rather than calling it but that defeats the purpous. class locationbox { function location() { $databaseconnect = new databaseconnect(); $databaseconnect -> connection();{ $result = mysql_query("SELECT * FROM locations"); while($row = mysql_fetch_array($result)) // line that now gets the error, mysql_fetch_array() expects parameter 1 to be resource, boolean given //in { echo "<option>" . $row['location'] . "</option>"; } } }} Well the title may seem a bit confusing, but heres an example: Code: [Select] <?php class User{ public $uid; public $username; protected $password; protected $email; public $usergroup; public $profile; public function __construct($id){ // constructor code inside } public function getemail(){ return $this->email; } public function getusergroup(){ return $this->usergroup; } public function getprofile(){ $this->profile = new UserProfile($this->uid); } } class UserProfile(){ protected $avatar; protected $bio; protected $gender; protected $favcolor; public function __construct($id){ // constructor code inside } public function formatavatar(){ // avatar formatting code inside } public function formatusername(){ // format username? } } ?> As you can see, the User class(an outer class) has a property called Profile, which can be instantiated as a UserProfile object(an inner class). The two objects have distinct functionalities, but there are times when the UserProfile object needs to access property and methods from the user object. I know its easy for outer class to access methods from inner class by using the single arrow access operator twice, but how about the other way around? Lets say from the above example the userprofile can format the username displayed to the screen by adding a sun to the left of the username if the usergroup is admin, a moon if the usergroup is mod, and nothing if its just a member. The usergroup property is stored in the outer class, and can be accessed with this $user->getusergroup() method only. I know I can always do the hard way by passing a user object to the method's argument, but is there an easier way for the inner class UserProfile to access properties/methods for outerclass User? If so, how can I achieve that? Hello! If you search Google, you'll notice the URL: http://www.google.com/webhp?hl=en#hl=en&source=hp&q=php+freaks&aq=f&aqi=g10&aql=&oq=&gs_rfai=CtdaTdtdRTNnPD5HuzASZtMWiCgAAAKoEBU_Q0ZT5&pbx=1&fp=19d754eee0b4f223 You can copy that URL anywhere you like... and the user will still see the same results. So basically the URL dynamically does an action, and accesses the database. How on do I make a URL like this? Meaning when you change the URL parameter values, it request a slightly different database query? Does that make sense? Similarly with NexTag.com: http://www.nextag.com/serv/main/buyer/ProductCompare.jsp?search=camera&page=0&node=500001&psort=%2FDigital-Cameras--zzcameraz500001zB6z5---html&zipcode=&cptitle=657166355&cptitle=656751324&cptitle=620051906&cptitle=705150048 That was a Dynamically made URL (I selected from check boxes which products to compare) and it makes that URL so anyone can see those products. Any ideas on how to do this? More examples on the URL: http://www.cars.com/go/compare/modelCompare.jsp?myids=9721,11439 (i select the cars, it generates that URL. Notice the IDs 9721,11439) I have a simple class like this: <?php class packet { private $SERVER = "192.168.1.100"; } ?> This works fine on localhost but on the server the $SERVER variable needs to be "72.20.32.58" instead. It's a pain having to keep changing this manually and using "localhost" doesn't work for some reason. I wanted to use $_SERVER['SERVER_ADDR'] but it errors when I use it. I have an issue with PHP/Apache which means I can't see the error that it returns. Can anyone tell me how I could set the $SERVER variable to $_SERVER['SERVER_ADDR'] in the class? Okay, so I want to take a stab at my first PHP class. Here is what I want it to do, but I'm not sure where to begin?! I have an HTML form in my index.php file, and when the user clicks "Register", I'd like to have registration.php which will contain the class Registration take what was entered in the form and print it out on the user's screen. This is an academic example, but it will get my feet wet! So, some questions... 1.) If registration.php is basically my Registration class, then where do I "instantiate" the class to create a "registration object"? 2.) How do I pass what was entered into the form to my registration class? Can you pass arguments to a class while you are instantiating it? Or do I instantiate the class, and then pass values to the object? Or do I let the object somehow get the values? 3.) I assume if I make it this far, then I can display the values by just having echo statements in the class/object, maybe as a method? Thanks, TomTees |