Basic OOP PHP form class - php

I'm just experimenting with OOP programming I'm trying to create a form class. I'm unable to print the checkbox, how can I check where things are going wronge?
require_once('form.php');
$gender = new Checkbox('Please select your gender','gender',array('male','female'));
echo $gender->show_checkbox();
File with class:
class Inputfield{
public $id;
public $options_array;
public $question;
public $type;
function __construct($newquestion,$newid,$newoptions_array){
$this->question=$newquestion;
$this->id=$newid;
$this->type="txt";
$this->options_array=$newoptions_array;
}
public function show_options($options_arr,$type,$id,$classes){
$output="";
foreach($options_arr as $option){
$output.="<label for=\"".$option."\"></label><input name=\"".$option."\" type=\"".$type."\" id=\"".$id."\" class=\"".$classes."\">";
}
return $output;
}
public function show_question(){
$output="<h3 class='question'>".$this->vraag."</h3>";
return $output;
}
}
class Checkbox extends Inputfield{
function __construct($newquestion,$newid,$newoptions_array){
$this->question=$newquestion;
$this->id=$newid;
$this->type="checkbox";
$this->options_array=$newoptions_array;
}
public function show_checkbox(){
$output=show_question();
$output.=show_options($this->options_array,'checkbox',$this->id,'class');
return $output;
}
}

You call instance methods with $this: $this->show_options();
You don't need to copy-paste the whole constructor as soon as it's identical to the one in parent class
In case if it matches partially you can call it like parent::__construct(...) and then define a custom $this->type="checkbox";
You can not define it in runtime but specify it as a property default value.

You should use $this in an object context. Eg. in your show_checkbox method, write:
$output = $this->show_question();
$output .= $this->show_options(...);

Related

Codeigniter Query result returning Custom result object with setters

How exactly does CI custome object works ?
As per CI documentation You can also pass a string to result() which represents a class to instantiate for each result object (note: this class must be loaded)
$query = $this->db->query("SELECT * FROM users;");
foreach ($query->result('User') as $row)
{
echo $row->name; // call attributes
echo $row->reverse_name(); // or methods defined on the 'User' class
}
}
This is a very nice feature yet what Ci does is it will return an array of User objects and set attributes from row to it.
i have a problem with it that i want to have more control on what attributes to be publicly accessed and what to be modified before setting/getting.
how can i accomplish this ? can i tell CI to pass all attributes to constructor so that class can populate its own data ?
example class User
class User{
private $data=array();
protected $CI;
//public $id,$name,$dob,$gender,$role,$username,$password,$salt,$picture,$lastactive;
function __construct($data=null)
{
$this->data = $data; // i want to save data to a private var and allow attr. throu getters only
}
function set_password($p){
$this->generateSalt();
$this->data->password = $p.$this->data->salt;
}
}
In a nutshell::
I want to use custom_result_object but i dont want codeigniter to populate class attributes for me, instead i want the class to receive those attrs and populate it him self the way he this its appropriate.
I found your question while looking for a solution for myself.
After digging a bit in the documentation I managed to figure it out:
class user_item {
// you can declare all the attributes you want as private
private $id,$name,$dob,$gender,$role,$username,$password,$salt,$picture,$lastactive;
function __construct(){
// you can use the constructor to format data as needed
$this->username = strtouppper($this->username);
}
public function set_password($p){
$this->generateSalt();
$this->password = $p.$this->salt;
}
public function get_password(){
return $this->password;
}
}
Once set up, you can instantiate this class from $this->db->result()
class User_model extends CI_Model {
public function get_user($id){
return $this->db->get_where('users', array('id' => $id), 1)->result('user_item');
}
}
And call any public method or attribute of the class as needed
class Users extends CI_Controller {
function __construct(){
$this->load->model('user');
}
public function profile($user_id){
var $myUser = $this->user->get_user($user_id);
$myUser->set_password('myPassword');
echo $myUser->get_password();
}
}
I have simplified the code to make it clearer, but you get the idea.
this example controller using result array and object
if ($this->session->userdata('id_jurusan') ==1) {
$where=array('id_jurusan'=>$this->session->userdata('id_jurusan'));
$value = $this->session->userdata('id_jurusan');
$value2 = $this->session->userdata('username');
$data['rule']=$this->guru_mod->get_where($where,'forward_changing')->result();
$data['fuzzy']=$this->guru_mod->get_data_all('fuzzy')->result();
$data['artikel']=$this->guru_mod->get_data_all('artikel')->result();
$data['kondisi']=$this->guru_mod->get_where($where,'kondisi')->result();
$data['artikel2'] = $this->guru_mod->get_data_all2('artikel','id_jurusan',$value);
$data['riwayat_rule'] = $this->guru_mod->get_data_all2('forward_changing','username',$value2);
$data['kondisi_rule'] = $this->guru_mod->get_data_all2('kondisi','id_jurusan',$value);
$this->load->view('guru/daftar_rule',$data);
}

Php error string conversion

I have this code. And i need to print those strings. But i can't make changes outside the class. So i need to change inside class to work. The fields must remain private. Any ideas?
class STUDENT {
private $nume,$prenume;
# Constructor
public function __construct($nume , $prenume){
$this->nume=$nume;
$this->prenume=$prenume;
}
}
$student = new STUDENT("one","two");
echo "student: ". $student ."<hr/>";
You have to define __toString method. Then you can echo instance as string:
class STUDENT {
private $nume,$prenume;
public function __construct($nume , $prenume){
$this->nume=$nume;
$this->prenume=$prenume;
}
public function __toString()
{
return '{nume:'.$this->nume.','.prenume:'.$this->prenume.'}';
}
}
$student = new STUDENT("one","two");
echo "student: ". $student ."<hr/>";
You need to use getters and setters so the fields can be read and written. Here's a discussion on the subject: Getter and Setter?

How do I use a variable within an extended class public variable

Have a class that I am using, I am overriding variables in the class to change them to what values I need, but I also not sure if or how to handle an issue. I need to add a key that is generated to each of this URLs before the class calls them. I cannot modify the class file itself.
use Theme/Ride
class ETicket extends Ride {
public $key='US20120303'; // Not in original class
public $accessURL1 = 'http://domain.com/keycheck.php?key='.$key;
public $accessURL2 = 'http://domain.com/keycheck.php?key='.$key;
}
I understand that you cannot use a variable in the setting of the public class variables. Just not sure what would be the way to actually do something like this in the proper format.
My OOP skills are weak. I admit it. So if someone has a suggestion on where I could read up on it and get a clue, it would be appreciated as well. I guess I need OOP for Dummies. =/
---- UPDATE ---
The initial RIDE class has 2 URLs set.
public $accessURL1 = "http://domain.com/index.php";
public $accessURL2 = "http://domain.com/index2.php";
I was to override them so the RIDE class will use my new domains.
I can add the following and it works...
class ETicket extends RIDE {
public $accessURL1 = 'http://mydomain.com/myindex.php';
public $accessURL2 = 'http://mydomain.com/myindex2.php';
}
However, I also want to pass a variable from elsewhere ($key) as a parameter to the URL when I override them so when i call RIDE it has a URL with the value of KEY at the end. (?key=keyvalue)
Your close, if you do not want to allow calling code to change the $key, you can do something like:
class ETicket extends Ride {
public function getKey()
{
return 'US20120303';
}
public function generateUrl()
{
return 'http://domain.com/keycheck.php?key=' . $this->getKey();
}
}
// Calling code example
$eTicket= new ETicket();
// $key is a member of ETicket class, so just call on generateUrl which will
// build and return the url
var_dump($eTicket->generateUrl());
You can also permit calling code to change the key if needed, by adding a public setter/getter:
class ETicket extends Ride {
protected $key;
public function setKey($key)
{
$this->key = $key;
}
public function getKey()
{
return $this->key;
}
public function generateUrl()
{
return 'http://domain.com/keycheck.php?key=' . $this->getKey();
}
}
// Calling code example
$eTicket= new ETicket();
$eTicket->setKey('US20120303');
var_dump($eTicket->generateUrl());
-- UPDATE --
There are a couple of options, you can either append the key to your url as part of the calling code, like this:
$eTicket= new ETicket();
$url = $ride->accessURL1 . '?key=US20120303';
Or, use a method (changed slightly to accept key directly) as I described earlier:
class ETicket extends Ride
{
public function generateUrl($key)
{
return $this->accessURL1 . '?key=' . $key;
}
}
$eTicket= new ETicket();
$url = $eTicket->generateUrl('US20120303');
I guess the point is, you cannot do what you originally asked without which is to concatenate a variable to a member variable initialization.

Create and use anonymous object in PHP

Say I have a simple class and I create it and call a function on it like this:
class tst
{
private $s = "";
public function __construct( $s )
{
$this->s = $s;
}
public function show()
{
return $this->s;
}
}
$t = new tst( "hello world" );
echo "showing " . $t->show() . "\n";
Is there any syntax or workaround that will allow me to instantiate an instance of tst and call the show() function without assigning the object to a variable? I want to do something like:
echo new tst( "again" )->show();
I don't want to declare my functions as static as I want to use them in both of the above examples.
You can't do what you want exactly, but there are workarounds without making things static.
You can make a function that returns the new object
function tst( $s ) {
return new tst( $s );
}
echo tst( "again" )->show();
To answer your question:
public static function create( $s )
{
return new tst($s);
}
public function show()
{
return $this->s;
}
The above will allow you to do tst::create("again")->show(). You can rename create as you like.
Agile Toolkit uses this approach everywhere. It uses add() method wrapper which is defined for global object ancestor. Here is some real-life code:
$page
->add('CRUD')
->setModel('User')
->setMasterField('admin',false);
This code creates 'CRUD' view, puts it on the page, creates and links with Model_User class instance which receives additional condition and default value for boolean 'admin' field.
It will display a CRUD control on the page with add/edit/delete allowing to edit all users except admins.
Here is code to describe concept:
class AbstractObject {
public $owner;
function add($class){
$c=new $class;
$c->owner=$this;
return $c;
}
}
class Form extends AbstractObject {
function dosomething(){
return $this;
}
}
class OtherForm extends Form {}
$object->add('Form')->dosomething()->owner
->add('OtherForm'); // etc
I think it's awesome and very practical approach.
p.s. I have to note new syntax for exceptions:
throw $this->exception('Something went bad');
using $this links exception to the object, which is at fault, which also can set default class for exception.

PHP: 'Dynamic' callback from inside/outside a class

we have a problem [cit.]
I need to assign a callback dynamically within a class, in base of a variable param: my goal is to have just one class (and not a main class and many extender sub-class), and inside this class if a value is X, then the funcitonX must be used, if is Y, the functionY.
I know i cant explain well, i hope my example will do:
class plzComplicateMyLife{
public $vehicle;
public $kindVehicle;
public $dynamicFunction;
public function __construct($vehicle, $kindVehicle){
$this->kindVehicle = $kindVehicle;
$this->vehicle = $vehicle;
switch($kindVehicle){
case 'cycle':
$this->dynamicFunction = "isACycle";
break;
case 'car':
$this->dynamicFunction = "isACar";
break;
}
//here come the problem, i need to call the callback store in dynamicFunction.
//i tried:
//call_user_func($this->$this->dinamicFunction, $this->vehicle);
//error: Catchable fatal error: Object of class plzComplicateMyLife could not be converted to string in [...]
//call_user_func("plzComplicateMyLife::".$this->dynamicFunction);
//Warning: call_user_func(plzComplicateMyLife::isACar) [function.call-user-func]: First argument is expected to be a valid callback in [...]
//$this->dynamicFunction();
//Fatal error: Call to undefined method plzComplicateMyLife::dynamicFunction() in [...]
//so, how can i do that?
}
public function isACycle($vehicle){
echo 'im a cycle, model: '.$vehicle.'<br />';
}
public function isACar($vehicle){
echo 'im a car, model: '.$vehicle.'<br />';
}
//i know this has no sense, in this example at least.
public function printKind(){
//call_user_func($this->$this->dinamicFunction, $this->vehicle);
//call_user_func("plzComplicateMyLife::".$this->dynamicFunction);
//then?
}
}
$maserati = new plzComplicateMyLife('maserati4', 'car');
//then, maybe, outside the class i'll need to recover the callback:
$maserati->printKind();
EDIT:
As Rob said, polymorphism would be really a good solution.
But the problem is that, in this case, i really must have the same declaration for every class instance, changing only the parameters...e.g:
$maserati = new plzComplicateMyLife('maserati4', 'car');
$ducati = new plzComplicateMyLife('maserati4', 'cycle');
//is good
//becose i cant have:
$maserati = new plzComplicateMyLifeWithACar('maserati4');
$ducati = new plzComplicateMyLifeWithACycle('maserati4');
Polymorphism is the way to go here but for future reference you can also do this:
public function printKind() {
$this->{$this->dynamicFunction}($this->vehicle);
}
In response to your edit, could you not do something like this instead?
abstract class MethodOfTransport {
protected $model;
public function __construct($model) {
$this->model = $model;
}
abstract public function printKind();
public static function create($model, $type) {
$object = new $type($model);
return $object;
}
}
class cycle extends MethodOfTransport {
public function printKind() {
echo 'im a cycle, model: '.$this->model.'<br />';
}
}
class car extends MethodOfTransport {
public function printKind() {
echo 'im a car, model: '.$this->model.'<br />';
}
}
$maserati = MethodOfTransport::create('maserati4', 'car');
$maserati->printKind();
$ducati = MethodOfTransport::create('maserati4', 'cycle');
$ducati->printKind();
In PHP you can use specify a method callback using an array as a callback variable (see here), for example:
array( $object, $methodName );
So you could do this
$callback = array($this, $this->dynamicFunction);
call_user_func($callback, $this->vehicle);
Er, why don't you want to use a simple inheritance structure here? If you want different behaviour depending upon the object modelled, then that's pretty much the canonical description of polymorphism.
If you really do want to plough on with callbacks into the same object, then you'll need to do one of two things:
Drop the $vehicle parameter from your callbacks, make them private or protected, and call into them normally, i.e.
call_user_func( array( $this, 'isACycle' ) );
Mark the callback as static, make them private or protected, and call into them as follows:
call_user_func( array( __CLASS__, 'isACycle' ), $this );
Within the non-static callback, access the object's properties via $this in the normal fashion. Note also that I suggest marking the callback as private or protected, in order to prevent unnecessary outside callers; presumably, you don't want them executing the wrong method for each type.

Categories