I'm using codeigniter and in controller folder, I created a php file like :
NOTE: connects database automaticly.
<?php
class Book extends CI_Controller {
$query = $this->db->get('books');
foreach ($query->result() as $row) {
function $row->book_name() {
echo $row->book_name;
}
}
}
?>
I tried to create functions by fetching book names from the database but I can not. By using $variable in function name, is it possible to create function? If not, How can create it in a quick way? Thanks...
Absolutely.
$myfunction = function($a,$b,$c) {return $a+$b+$c;};
This is an example of an anonymous function. It has no name, but it can be accessed by $myfunction(1,2,3).
I'm not entirely sure what you're trying to do in your example... Should just echo $row->book_name alone be enough? Or are you trying to define a function with the same name as a book? In the latter case, you can use variable variables: ${$row->book_name} = function... - it's probably not a good idea though.
I think you may be interested in __call().
If a call is made to a method in a class that does not exist, the __call() method is invoked and you can handle the call from there.
Store the books in an array as you read the results, and add a __call method to your class. When the method is accessed, you can search the array for the book based on the name of the function called and act appropriately.
class Book extends CI_Controller {
protected $_books = array();
public function __construct() {
$query = $this->db->get('books');
foreach ($query->result() as $row) {
$this->_books[] = $row->book_name;
}
}
public function __call($name, $arguments) {
if (in_array($name, $this->_books)) {
echo $name;
} else {
ehco 'I do not have this book!';
}
}
}
Just keep in mind PHP's rules for naming methods, a valid function name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. No spaces are allowed so keep that in mind.
Is it create_function() that you are searching for?
But seriously, it took me a minute to google it..
Related
Before anyone says anything. I've been to many articles, and I just can't wrap my head around the purpose of a constructor.
I've found an example on a site. Here's the code:
<?php
class dogtag {
public $Words;
}
class dog {
public $Name;
public $DogTag;
public function bark() {
print "Woof!\n";
}
public function __construct($DogName) {
print "Creating $DogName\n";
$this->Name = $DogName;
$this->DogTag = new dogtag;
$this->DogTag->Words = "My name is $DogName. If you find me, please call 555-1234";
}
}
class poodle extends dog {
public function bark() {
print "Yip!\n";
}
}
$poppy = new poodle("Poppy");
print $poppy->DogTag->Words . "\n";
?>
It echoes out the following:
Creating Poppy My name is Poppy. If you find me, please call 555-1234
May someone please explain this code to me like I'm 5. I just don't get it.
A constructor is used to do any initial process required once a new class object was initiated. Ok so that was pretty fancy right? Lets break down what that means with an example. Lets first make a class, and inside that class put some variables, some functions, and a constructor! (It's easier for me to explain the concept behind a constructor with a simpler class. babysteps.)
<?php
class myInfo
{
protected $limit;
public function __construct($limit = 10)
{
$this->limit = $limit;
}
public function awesomesauce() {
//...some random code...
}
}
$variable = new myInfo();//initiating an instance of class myInfo
?>
The code $variable = new myInfo(); is initiating an object of type myInfo. When that initiation happened, the php code knows that right away, the constructor function public function __construct($limit = 10) has to be called. In this case, the value of $limit is made to be 10. However, if I later on do the following code:
$variableTwo = new myInfo(20);
The variable passed inside the parenthesis would be passed directly into the constructor function.
So depending on the specific situation I could either pass no variables when creating an instance of type myInfo, in which case the constructor function would use the default value of ($limit = 10) or I could pass a value. If php did not have the ability to use constructors, I would literally have to manually change that variable with a new line of code every time I initiated a new object of class myInfo. Now this is just a simple example. Imagine if you need to not only initiate values, but run functions that work with API's somewhere else on your server. You can definitely see the benefit of having this happen automatically instead of being forced to write multiple lines of code every single time an object is initiated.
Let me know if that helped.
I have a class that executes eval statements within a (very large) loop. The eval statements are database stored code (mixed html & php) that needs to be processed. There is however is a serious performance issue because of this.
Instead of parsing the eval-statement every time in the loop, I would like to create a dynamic methods from the available eval-codes coming from the database within my class.
I thought of the following pseudocode so that the eval code is converted to a method:
class foo
{
private $test=3;
public function doloop()
{
for($i=0;$i<5;$i++)
{
$string="echo 50 * \$this->test.'<br>';";
$func="evalcode_001";
if(!isset(${$func}))
{
${$func}=create_function('',$string);
}
${$func}();
}
}
}
$obj_foo = new foo();
$obj_foo->doloop();//must output '150<br>150<br>150<br> .....'
However when running it I get the error message "Using $this when not in object context in ...". So obviously I didn't really create methods within the class.
So my question is:
How do I create a method for a class dynamically and assign code for the given method. Basically I want to be able to do:
$obj_foo->evalcode_001();
in the above example.
Help appreciated
PS I am using PHP5.4
If you can change $this->test inside string (or write extra preg_match) you can use:
<?php
class foo
{
public $test=3;
public $functions = array();
public function doloop()
{
for($i=0;$i<5;$i++)
{
$string="echo 50 * \$this->test.'<br>';";
$func="evalcode_001";
if(!isset($this->functions[$func]))
{
$string = str_replace('$this','$object', $string );
$this->functions[$func]= create_function('$object',$string);
}
$this->functions[$func]($this);
}
}
public function __call($name, $arguments) {
if (isset($this->functions[$name])) {
return $this->functions[$name]($this);
}
}
public function otherMethod() {
echo "test";
}
}
$obj_foo = new foo();
$obj_foo->doloop();//must output '150<br>150<br>150<br> .....
$obj_foo->evalcode_001();
$obj_foo->otherMethod();
However as other said I wouldn't like to use anything like that in my real script
I'm struggling to find a correct approach to pass data between classes, which do not directly call each other, and are only related through a parent class (which I now use, but I consider it a dirty workaround rather than anything near a solution).
I have 3 classes both able to read input and write output, and based on configuration I set one to read, another one to write. It may even be the same class, they all share a parent class, but they are always two separate instances called from a controller class.
Currently I use this sort of functionality:
class daddy {
public static $data;
}
class son extends daddy {
public function setData() {
parent::$data = "candy";
}
}
class daughter extends daddy {
public function getData() {
echo parent::$data;
}
}
while($processALineFromConfig)
$son = new son;
$son->setData();
$daughter = new daughter;
$daughter->getData();
daddy::$data = null; //reset the data, in the actual code $daughter does that in parent::
}
Instantination of these classes runs in a loop, therefore I always need to reset the data after $daughter receives them, 'cos otherwise it would stay there for another pass through the loop.
I'm absolutely sure it's not how class inheritance is supposed to be used, however I'm struggling to find a real solution. It only makes sense the data should be stored in the controller which calls these classes, not the parent, but I already use return values in the setter and getter functions, and I am not passing a variable by reference to store it there to these functions 'cos I have optional parameters there and I'm trying to keep the code clean.
What would be the correct approach to pass data through the controller then?
Thanks!
The best option would be for two object share some other, third object. This would be the class for "third object" which will ensure the exchage:
class Messenger
{
private $data;
public function store($value)
{
$this->data = $value;
}
public function fetch()
{
return $this->data;
}
}
Then a class for both instance, that will need to share some state:
class FooBar
{
private $messenger;
private $name = 'Nobody';
public function __construct($messenger, $name)
{
$this->messenger = messenger;
$this->name = $name;
}
public function setSharedParam($value)
{
$this->messenger->store($value);
}
public function getSharedParameter()
{
return $this->name . ': ' . $this->messenger->fetch();
}
}
You utilize the classes like this:
$conduit = new Messenger;
$john = new FooBar($conduit, 'Crichton');
$dominar = new FooBar($conduit, 'Rygel');
$dominar->setSharedParameter('crackers');
echo $john->getSharedParameter();
// Crichton: crackers
Basically, they both are accessing the same object. This also can be further expanded by making both instance to observe the instance of Messenger.
What is the best way to make a variable accessable to all classes.
For example, I want to have a configuration file (Call it config.php) that is going to have a variable like so:
$server_url = "www.myaddress.com";
And I have a main library type file that contains a bunch of classes that need to access the $server_url. So here begins that main library file:
require 'config.php';
class one {
function a() {
$html = "<a href='$server_url/main.php'>LINK</a>"
return $html;
}
function b() {
$html = "<a href='$server_url/about.php'>LINK</a>"
return $html;
}
}
class two {
function new() {
$html = "<a href='$server_url/blah.php'>LINK</a>
}
}
What would be the best way to make $server_url from the config.php available to every function? Or at least available to all the functions in a class?
Personally I would use a static entity to hold all configuration values.
Usually, most php applications have a single entry point (index.php) that can load up the config.php file and make the static entity available from that point.
If your application has multiple entry points, then you will need to include config.php in each of these points.
Something like this:
<?php
class Configurator{
private static $_configuration = array();
public static function write($key, $value) {
self::$_configuration[$key] = $value;
}
public static function read($key) {
return self::$_configuration[$key];
}
}
Configurator::write('server', 'http://localhost');
Configurator::read('server');
?>
CakePHP has a similar class: http://api.cakephp.org/view_source/configure/
Make the config into a class in itself and use a static methods either along the line of serverUrl() or get('server_url'). Then call them like any other static methods to classes (I'll choose the latter in this example):
$html = "<a href='" . Config::get ('server_url') . "/main.php'>LINK</a>";
The config class could be pretty slim, use a constructor like:
public function __construct (array $config)
{
foreach ($config as $key => $value)
{
$this->$key = $value;
}
}
And add the get() method along these lines:
public function get ($key)
{
return $this->$key;
}
This way you can read the config from an array that you can have as a separate, actual config file, and reuse the same code for multiple projects.
You'll also be able to access the variables from anywhere in the project and you'll get a sort of pseudo-namespacing (in case the project needs to run on an older version of PHP).
Please, don't copy the code verbatim, it's written as an example.
think of globals are evil. Try to use design patterns to get access to some configs globally.
I'm a big fan of singletons to get global access to objects, arrays or other data-types.
<?php
class st {
static $_this;
function __construct(){
self::$_this = $this;
}
static function &getInstance(){
return self::$_this
}
static function set($key, $value){
self::$_this[$key] = $value;
}
static function &get($key){
return self::$_this[$key];
}
}
// Usage
new st();
st::set('foo', 'bar');
// In some class
st::get('foo'); //return 'bar'
// Or when there are some classes/objects
st::getInstance()->foo->bar();
$st =& st::getInstance();
$st->foo->bar();
?>
Roughly wrote down a small singleton, but don't know whether there is a syntax error.
While handling with getInstance it's certain that you define the variable by reference =&
Define a constant in config.php like:
define('SERVER_URL', '...');
In your class:
echo SERVER_URL;
What works for me the best is to use a config file like config.ini
And then to use $my_config = parse_ini_file(file path/config.ini');
Now everywhere in my code including inside functions and classes, I will use
The PHP superglobal like this:
$GLOBALS["my_config"]['my_global_var']
I've got a bunch of functions that I want to move into a class. They're currently split into a couple of fairly long files. I'd prefer not to have one 2500 line file, but as far as I can tell, you can't use include to split a class up into multiple files. In theory, I could group the functions in different classes, but they're closely related enough that I feel like they belong together, and splitting them will reduce some of the utility that I'm hoping to get from moving away from a procedural approach (with shared properties, rather than a bunch of parameters that are in nearly every function).
I know this is a bit vague, but any suggestions/pointers? If it matters, this is for a prototype, so ease of code management takes precedence over security and performance.
UPDATE: Let me see if I can remove some of the vagueness:
This class/set of functions outputs the html for a complex form. There are many different sections and variations within each section, depending on about 5 or 6 parameters, which are currently passed into the functions. I was hoping to define the parameters once as properties of the class and then have access to them from within all of the section-creation methods. If I use sub-classes, the values of those properties won't be initialized properly, hence the desire for one class. (Hmm... unless I define them as static. I may have just answered my own question. I'll have to look to see if there's any reason that wouldn't work.)
I've currently got a mess of functions like:
get_section_A ($type='foo', $mode='bar', $read_only=false, $values_array=array()) {
if ($this->type == 'foo') { }
else ($this->type == 'foo') { }
}
So I was initially imagining something like:
class MyForm {
public $type; // or maybe they'd be private or
public $mode; // I'd use getters and setters
public $read_only; // let's not get distracted by that :)
public $values_array;
// etc.
function __constructor ($type='foo', $mode='bar', $read_only=false, $values_array=array()) {
$this->type = $type;
// etc.
}
function get_sections () {
$result = $this->get_section_A();
$result .= $this->get_section_B();
$result .= $this->get_section_C();
}
function get_section_A() {
if ($this->type == 'foo') { }
else { }
}
function get_section_B() {}
function get_section_C() {}
// etc. for 2500 lines
}
Now I'm thinking something like:
// container class file
class MyForm {
static $type
static $mode
static $read_only
static $values_array
// etc.
function __constructor ($type='foo', $mode='bar', $read_only=false, $values_array=array()) {
MyForm::$type = $type;
// etc.
}
function get_sections () {
$result = new SectionA();
$result .= new SectionB();
$result .= new SectionC();
}
}
// section A file
class SectionA extends MyForm {
function __constructor() {
if (MyForm::$type == 'foo') { }
else { }
}
function __toString() {
// return string representation of section
}
}
// etc.
Or probably I need an abstract class of FormSection where the properties live.
Any other ideas/approaches?
I'd split them up into as many classes as you want (or as many that make sense) and then define an autoloader to obviate inclusion headaches.
EDIT
Ok, after seeing more of your code - I think you're approaching subclasses wrong. You have lots of if statements against $type, which signals to me that that is what the polymorphism should be based on.
abstract class MyForm
{
protected
$mode
, $read_only
, $values
;
public function __construct( $mode, $read_only=false, array $values = array() )
{
$this->mode = $mode;
$this->read_only = (boolean)$read_only;
$this->values = $values;
}
abstract function get_section_A();
abstract function get_section_B();
abstract function get_section_C();
// final only if you don't want subclasses to override
final public function get_sections()
{
return $this->get_section_A()
. $this->get_section_B()
. $this->get_section_C()
;
}
}
class FooForm extends MyForm
{
public function get_section_A()
{
// whatever
}
public function get_section_B()
{
// whatever
}
public function get_section_C()
{
// whatever
}
}
Usually I do something like this:
class one
{
public function __get($key)
{
// require __DIR__ / $key . php
// instanciate the sub class
}
public function mainMethod()
{
}
}
class one_subOne extends one
{
public function otherMethod()
{
}
}
class one_subTwo extends one
{
public function anotherMethod()
{
}
}
$one->mainMethod();
$one->subOne->otherMethod();
$one->subTwo->anotherMethod();
As far as building the view is concerned, you might like to try the CompositeView pattern.
Here's a small example of how it could look in PHP. Pretend, for the sake of this example, that View::$html is encapsulated in a Template class that can load html from disk and allows you to inject variables, handles output escaping, etc.
interface IView {
public function display();
}
class View implements IView {
public $html = '';
public function display() {
echo $this->html;
}
}
class CompositeView implements IView {
private $views;
public function addPartial(IView $view) {
$this->views[] = $view;
}
public function display() {
foreach ($this->views as $view) {
$view->display();
}
}
}
The reason for the IView interface is to allow you to build composite views with other composite views.
So now consider a form with three parts: header, body and footer.
class HeaderView extends View {
public function __construct() {
$this->html .= "<h1>Hi</h1>\n";
}
}
class BodyView extends View {
public function __construct() {
$this->html .= "<p>Hi there.</p>\n";
}
}
class FooterView extends View {
public function __construct() {
$this->html .= "<h3>© 2012</h3>\n";
}
}
(Again, you wouldn't just write HTML into that public variable and handle output escaping yourself. You'd likely reference a template filename and register your data via the template's interface.)
Then, to put it all together you would go:
$view = new CompositeView();
// here you would make decisions about which pieces to include, based
// on your business logic. see note below.
$view->addPartial(new HeaderView());
$view->addPartial(new BodyView());
$view->addPartial(new FooterView());
$view->display();
So now your views can be composed and the fragments reused, but you can easily make a mess with the code that builds them, especially if you have a lot of conditions and many different possible outcomes (which it sounds like you do.) In that case, the Strategy pattern will probably be of some help.
If you haven't already read UncleBob's SOLID article, do it before anything else! At least the Single Responsibility Principle. I would also recommend reading Refactoring to Patterns by Joshua Kerievsky at some point.
If you want to do OOP, separate the concerns and encapsulate them into appropriate classes. Combine them either by extending them or by composition or better aggregation. Remove any duplicate code. Dont repeat yourself.
In your case, separate the stuff that is about any Form from the stuff that is about your specific form. The code that can be used for any Form is the code you want to place into a generic Form class. You can reuse this in later projects. For an example of a very complex Form class, check out Zend_Form.
Anything in your code related to the/a specific form gets into a class of it's own that extends the generic form. Assuming from the type property given in your code, you might end up with multiple special purpose form classes (instead of one-type-fits-all-form), which will likely eliminate the complexity from the getSection methods and make your code a lot easier to maintain because you can concentrate on what a specific type of form is supposed to look like and do.
Lastly, if you got code in there that fetches data for the form from within the form or is otherwise not directly related to form building, remove it and make it into a separate class. Remember, you want to separate concerns and your form classes' concern is to build a form, not get it's data or something. Data is something you will want to pass to the form through the constructor or a dedicated setter.
They are all in different files, which means that they were different enough to group by file. Just take the same logic when building them into classes. I have a Page object that deals with building the page. Technically the HTML for my page header is part of the page, but I separate it into a Page_HTML class for maintaining my sanity and not creating gigantic classes.
Also, I tend to make the sub_classes, like Page_HTML in this case, static, instead of instantiating it. That way I can access the $this variables in the Page class, but still group it into another class.
class Page
{
function buildPage($content)
{
$content = Page_HTML::getHeader() . $content;
}
}
class Page_HTML
{
function getHeader()
{
}
}
This class/set of functions outputs
the html for a complex form.
Why not remove PHP from the equation? It seems you're using PHP to organize views which can be done easily with the filesystem. Just write the views in HTML with as little PHP as possible. Then use PHP to map requests to views. I'm assuming you're processing forms with PHP, and you could continue to do so. However, your classes will become much smaller because they're only accepting, verifying and presumably saving input.