Guest FirefoxRocks Posted July 17, 2009 Share Posted July 17, 2009 So now I just learned that PHP is an object-orientated language. From what I've read, objects are crucial for larger web applications.Well I have no clue what an object is, or a class, or anything like that. It took me a while to grasp the concept of a function in JavaScript, which then I learned how to use in both JavaScript and PHP. At first I thought all functions were predefined but then I learned you could create your own functions to do stuff repetitively.So can someone explain to me stuff about object-orientated programming, objects, classes and anything I need to know about this? That would be greatly appreciated. Thanks. Link to comment Share on other sites More sharing options...
Synook Posted July 17, 2009 Share Posted July 17, 2009 PHP can be object-oriented, but it is firstly a procedural language. Object Oriented Programming (OOP) is not "crucial", but in many instances it helps keep large amounts of code flexible and easy to use.Object Orientation is basically focusing on the data, instead of the procedure, by bundling all the algorithms necessary for operating on some data into encapsulated packages called classes. When you have some data that you need working on, you create an instance of the relevant class and use it.The best option for you is to get a nice book on the subject. Can't think of any at the moment, but I'm sure someone else can. There is a lot to OO, you can't learn it well in a forum.JavaScript is quite interesting as it is one of the few well-used examples of a type of object-orientated programming called classless, or prototype-based, programming. In prototype-based languages, there are no classes, as such, and instead everything is already an object that can be cloned (i.e. through the use of the new keyword) and extended along their prototype (e.g. object.prototype in JS). PHP is not classless, instead of going directly ahead and creating an object you first need to create a class of objects (e.g. class MyClass { }) and then create instances of that object (e.g. $me = new MyClass(); ). Link to comment Share on other sites More sharing options...
NurAzije Posted July 17, 2009 Share Posted July 17, 2009 You can find good informations in this article http://www.devarticles.com/c/a/PHP/Object-...ramming-in-PHP/ Link to comment Share on other sites More sharing options...
boen_robot Posted July 17, 2009 Share Posted July 17, 2009 The basic concept that you need to first become familliar with is that classes are a set of functions and variables (reffered to as "methods" and "properties" respectively) that continiously have access to everything within the class. More importantly, each "instance" of a class (reffered to as "object") can have a different set of values for its "properties", thereby allowing "methods" to do different stuff for each "object".For example: <?phpclass A { $b = 0; function c() { return $this->b; }}$x = new A;//At this point, the properties are as we defined them, i.e. $b = 0$x->b = 1;//At this point, we changed $b to 1$y = new A;//At this point, the properties are as we defined them, i.e. $b = 0$y->b = 2;//At this point, we changed $b to 2echo $x->c(), $y->c();//Ouputs 12, because the $b of the first object is 1, and the $b of the second object is 2.?> If you can grasp THAT, the rest should be easy enough to learn. Refer to the materials suggested already, and of course, the PHP manuals' section on OOP. Link to comment Share on other sites More sharing options...
justsomeguy Posted July 17, 2009 Share Posted July 17, 2009 Most people use classes to wrap similar functions in the same package. A template engine will be implemented as a class, where you create an instance of the template, tell it which template file to use, give it data, tell it to generate output, etc. You can use the class without knowing the details about how it works, they call that black-box programming. The analogy is a toaster, you can press the button on a toaster and use it to toast bread without needing to know electronically how the toaster actually works. Here are a few classes I use on various applications:This is my session class, I use this to replace the $_SESSION array, and it includes things to log a user in, redirect, log out, etc. This is using the database structure for my application, so it might not fit to something you're doing, but it should give an idea: <?phpclass tc_lms_session{ public $userid = 0; public $username = ''; public $fullname = ''; private $password = ''; public $userdata = false; public $error = ''; public $error_field = ''; public $main_admin = false; public $sub_admin = false; public $ug_admin = false; public $any_admin = false; public $data = false; function __construct($u = '', $p = '') { session_start(); if (isset($_SESSION['userid'])) { $this->userid = $_SESSION['userid']; $this->userdata = $_SESSION['userdata']; $this->username = $this->userdata['username']; $this->fullname = $this->userdata['fname'] . ' ' . $this->userdata['lname']; $this->main_admin = $this->userdata['main_admin']; $this->sub_admin = $this->userdata['sub_admin']; $this->ug_admin = $this->userdata['ug_admin']; $this->any_admin = $this->main_admin || $this->sub_admin || $this->ug_admin; if (isset($_SESSION['data'])) $this->data = $_SESSION['data']; else $this->data = array(); } if ($u != '') { $this->username = $u; $this->password = $p; $this->login(); } } function login($u = '', $p = '') { global $db; if ($u != '') { $this->username = $u; $this->password = $p; } $db->sql("SELECT * FROM users WHERE username = %s"); $db->add_param($this->username); $result = $db->select(); if (!$result) { $this->error_field = 'username'; $this->error = 'The username was not found.'; return false; } if ($this->password != $result[0]['password']) { $this->error_field = 'password'; $this->error = 'The password was not correct.'; return false; } if ($result[0]['active'] == 0) { $this->error_field = 'username'; $this->error = 'The user account is not active.'; return false; } $now = time(); $db->update('users', array('last_login' => $now, 'last_ip' => $_SERVER['REMOTE_ADDR']), "id={$result[0]['id']}"); $prev = $result[0]['last_login']; $result[0]['last_login'] = $now; $result[0]['last_ip'] = $_SERVER['REMOTE_ADDR']; $this->userid = $result[0]['id']; $this->fullname = $result[0]['fname'] . ' ' . $result[0]['lname']; $this->userdata = $result[0]; $this->main_admin = $result[0]['main_admin']; $this->sub_admin = $result[0]['sub_admin']; $this->ug_admin = $result[0]['ug_admin']; $this->any_admin = $this->main_admin || $this->sub_admin || $this->ug_admin; $this->error = ''; $this->error_field = ''; $_SESSION['userid'] = $this->userid; $_SESSION['userdata'] = $this->userdata; if (!$this->any_admin) $this->set_val('previous_login', $prev); if (isset($_SESSION['data'])) $this->data = $_SESSION['data']; else $_SESSION['data'] = $this->data = array(); return true; } function logout() { $this->userid = 0; $this->userdata = false; $this->main_admin = false; $this->sub_admin = false; $this->ug_admin = false; $this->any_admin = false; //$_SESSION = array(); //session_destroy(); if (isset($_SESSION['data'])) unset($_SESSION['data']); if (isset($_SESSION['userid'])) unset($_SESSION['userid']); if (isset($_SESSION['userdata'])) unset($_SESSION['userdata']); if (isset($_SESSION['cache'])) unset($_SESSION['cache']); } function update($data) { foreach ($data as $k => $v) { if (isset($this->$k)) $this->$k = $v; if (isset($this->userdata[$k])) $this->userdata[$k] = $v; } $this->fullname = $this->userdata['fname'] . ' ' . $this->userdata['lname']; $_SESSION['userdata'] = $this->userdata; } function set_user($id) { global $db; unset($_SESSION['userid']); unset($_SESSION['userdata']); $this->userid = $id; $db->sql("SELECT * FROM users WHERE id = %d"); $db->add_param($id, false); $result = $db->select(); if (!$result) { $this->error_field = 'username'; $this->error = 'The username was not found.'; return false; } if ($result[0]['active'] == 0) { $this->error_field = 'username'; $this->error = 'The user account is not active.'; return false; } $this->userid = $result[0]['id']; $this->fullname = $result[0]['fname'] . ' ' . $result[0]['lname']; $this->userdata = $result[0]; $this->main_admin = $result[0]['main_admin']; $this->sub_admin = $result[0]['sub_admin']; $this->ug_admin = $result[0]['ug_admin']; $this->any_admin = $this->main_admin || $this->sub_admin || $this->ug_admin; $this->error = ''; $this->error_field = ''; $_SESSION['userid'] = $this->userid; $_SESSION['userdata'] = $this->userdata; return true; } function set_val($name, $val) { $_SESSION['data'][$name] = $this->data[$name] = $val; } function get_val($name) { return (isset($this->data[$name]) ? $this->data[$name] : ''); } function redirect($url) { if (strpos($url, '?') === false) $url .= '?'; else $url .= '&'; $url .= SID; session_write_close(); header('Location: ' . $url); exit(); }}?> Here's my database class, I use this to do all database work. It will automatically escape values, it returns an array of records instead of a resource, and has several utility methods: <?phpclass tc_lms_database{ private $host = ''; private $user = ''; private $pass = ''; private $db = ''; private $conn = false; public $sql_stmt = ''; public $params = false; private $result = false; private $rowset = false; private $last_stmt = ''; /* Constructor Set the host, username, password, and database, then connect */ function __construct($h = '', $u = '', $p = '', $d = '') { if ($h != '') { $this->host = $h; $this->user = $u; $this->pass = $p; $this->db = $d; $this->connect(); } } /* connect Connect to the database using the supplied information, trigger an error if there was a problem */ function connect($h = '', $u = '', $p = '', $d = '') { if ($h != '') { $this->host = $h; $this->user = $u; $this->pass = $p; $this->db = $d; } $this->conn = mysql_connect($this->host, $this->user, $this->pass) or trigger_error(mysql_error(), E_USER_ERROR); if ($this->db != '') mysql_select_db($this->db, $this->conn) or trigger_error($this->error(), E_USER_ERROR); } /* reset Reset the SQL statement and all parameters */ function reset() { $this->sql_stmt = ''; $this->params = false; } /* sql Set the SQL statement */ function sql($str) { $this->sql_stmt = $str; } /* add_param Add a parameter for the SQL statement, and optionally escape it. Parameters should be added in the same order that they appear in the SQL */ function add_param($val, $escape = true) { if ($escape) $val = "'" . $this->escape($val) . "'"; if (!$this->params) $this->params = array(); $this->params[] = $val; } /* exec Execute a SQL statement and return the result. If the argument is true, do not die on an error. This returns a mysql result resource. */ function exec($passthrough_errors = false) { $this->check_db(); if ($this->sql_stmt == '') trigger_error('SQL statement not set', E_USER_ERROR); if (is_array($this->params) && count($this->params)) { $this->sql_stmt = vsprintf($this->sql_stmt, $this->params); $this->params = false; } $this->last_stmt = $this->sql_stmt; if ($passthrough_errors) return mysql_query($this->sql_stmt); else return mysql_query($this->sql_stmt) or trigger_error($this->error(), E_USER_ERROR); } /* get_row Get a single row from the given result set */ function get_row($result) { return mysql_fetch_assoc($result); } /* select Execute a SELECT statement, with an optional limit and page number. This returns the results as an array of rows, not as a mysql result resource. e.g.: $db->select(10, 3); // get the 10 items on page 3 */ function select($limit = 0, $page = 0) { $this->check_db(); if ($this->sql_stmt == '') trigger_error ('SQL statement not set', E_USER_ERROR); if (is_array($this->params) && count($this->params)) { $this->sql_stmt = vsprintf($this->sql_stmt, $this->params); $this->params = false; } if ($limit) { $this->sql_stmt .= ' LIMIT '; if ($page) $this->sql_stmt .= (($page - 1) * $limit) . ','; $this->sql_stmt .= $limit; } $this->last_stmt = $this->sql_stmt; $this->result = mysql_query($this->sql_stmt) or trigger_error($this->error(), E_USER_ERROR); $this->rowset = array(); while ($row = mysql_fetch_assoc($this->result)) { // convert null to empty string foreach ($row as $k => $v) { if (is_null($v)) $row[$k] = ''; } $this->rowset[] = $row; } mysql_free_result($this->result); return $this->rowset; } /* delete Execute a DELETE statement with an optional limit */ function delete($limit = 0) { $this->check_db(); if ($this->sql_stmt == '') trigger_error('SQL statement not set', E_USER_ERROR); if (is_array($this->params) && count($this->params)) { $this->sql_stmt = vsprintf($this->sql_stmt, $this->params); $this->params = false; } if ($limit) $this->sql_stmt .= " LIMIT {$limit}"; $this->last_stmt = $this->sql_stmt; return mysql_query($this->sql_stmt) or trigger_error($this->error(), E_USER_ERROR); } /* insert Insert a record into the given table. The $params variable should be an associative array of column names and values. e.g.; $db->insert('table_name', array('id' => 10, 'username' => 'Joe')); */ function insert($table, $params) { $this->check_db(); if (!is_array($params) || count($params) == 0) return false; $names = ''; $values = ''; foreach ($params as $k => $v) { $names .= "{$k},"; $values .= "'" . $this->escape($v) . "',"; } $names = substr($names, 0, -1); $values = substr($values, 0, -1); $this->last_stmt = "INSERT INTO {$table} ({$names}) VALUES ({$values})"; return mysql_query("INSERT INTO {$table} ({$names}) VALUES ({$values})", $this->conn) or trigger_error($this->error(), E_USER_ERROR); } /* update Update a record in the given table. Similar to insert, but the third parameter is the expression to use in the WHERE clause. e.g.: $db->update('table_name', array('username' => 'John'), 'id=10'); */ function update($table, $params, $where = '') { $this->check_db(); if (!is_array($params) || count($params) == 0) return false; $cols = ''; foreach ($params as $k => $v) $cols .= "{$k}='" . $this->escape($v) . "',"; $cols = substr($cols, 0, -1); if ($where != '') $where = " WHERE {$where}"; $sql = "UPDATE {$table} SET {$cols} {$where}"; $this->last_stmt = $sql; return mysql_query($sql, $this->conn) or trigger_error($this->error(), E_USER_ERROR); } /* escape Escape a string for use in a query */ function escape($str) { /* if (get_magic_quotes_gpc()) $str = stripslashes($str); */ return mysql_real_escape_string($str, $this->conn); } /* strip Remove selected characters from a string */ function strip($str) { $replace = array( "'", '"', '-', ';' ); return str_replace($replace, '', $str); } /* insert_id Get the last autoassigned ID */ function insert_id() { return mysql_insert_id($this->conn); } /* num_rows Get the number of rows produced by the given SQL statement */ function num_rows($sql) { return mysql_num_rows(mysql_query($sql, $this->conn)); } /* check_db Make sure the database has been connected to */ function check_db() { if ($this->conn == false) die('Database not initialized'); } /* error Generate the last error message */ function error() { global $page_mode, $sess; if (empty($page_mode)) $page_mode = ''; return 'Page mode: ' . $page_mode . '; User ID: ' . $sess->userid . '; Database Error #' . mysql_errno($this->conn) . ': ' . mysql_error($this->conn) . '. SQL Query: ' . $this->last_stmt; } /* get_last_sql Get the last SQL statement executed, after parameter replacement */ function get_last_sql() { return $this->last_stmt; }}?> Here's a smaller class I made for just handling config options in the database. The first time you get an option it will load all options from the database and store them in an array, so it only uses 1 database lookup regardless of how many options there are. When you update an option, it will only update the value in the array in memory (not the database yet), and then when the script ends and the object is about to get destroyed it will look through the options to see if any values have changed, and update the database with the new values. <?phpclass tc_lms_config{ private $fields; private $dirty; private $db; private $debug; private $fpath; private $db_keys; function __construct() { global $db; /* Why it is necessary to keep a reference to global db: This class uses the db object in the destructor. There is no guarantee which order objects will get destroyed in. An object will not get destroyed if there are references to it somewhere else. Storing a reference to the global db object in this class ensures that this object will be available for the destructor to use. A side-effect of this is that this class requires the db object to have already been created when an object of this class is instantiated. */ $this->debug = false; $this->fpath = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'config.log'; $this->fields = array(); $this->dirty = array(); $this->db_keys = array(); $this->db = $db; if ($this->debug) file_put_contents($this->fpath, date('r') . " Config class created\n", FILE_APPEND); } function __destruct() { # commit changes $tmp = array(); foreach ($this->dirty as $k => $v) { $tmp[] = $k; $update = array('val' => $this->fields[$k]); if (in_array($k, $this->db_keys)) $this->db->update('config', $update, "`name`='{$k}'"); else $this->db->insert('config', array('name' => $k, 'val' => $this->fields[$k])); } if ($this->debug) file_put_contents($this->fpath, date('r') . " Config class destroyed. Updates:\n" . print_r($tmp, true), FILE_APPEND); } function get_opt($id) { if ($this->debug) file_put_contents($this->fpath, date('r') . " Get option ({$id})\n", FILE_APPEND); if (!count($this->fields)) $this->load_opts(); if (isset($this->fields[$id])) { if ($this->debug) file_put_contents($this->fpath, date('r') . " Value: {$this->fields[$id]}\n", FILE_APPEND); return $this->fields[$id]; } if ($this->debug) file_put_contents($this->fpath, date('r') . " Option not found\n", FILE_APPEND); return false; } function load_opts() { if ($this->debug) file_put_contents($this->fpath, date('r') . " Load options\n", FILE_APPEND); $this->db->sql('SELECT * FROM config ORDER BY `name` ASC'); $results = $this->db->select(); for ($i = 0; $i < count($results); $i++) { $this->fields[$results[$i]['name']] = $results[$i]['val']; $this->db_keys[] = $results[$i]['name']; } if ($this->debug) file_put_contents($this->fpath, date('r') . " Options loaded:\n" . print_r($this->fields, true), FILE_APPEND); } function set_opt($id, $val) { if ($this->debug) file_put_contents($this->fpath, date('r') . " Set option ({$id}, {$val})\n", FILE_APPEND); if (!count($this->fields)) $this->load_opts(); $this->fields[$id] = $val; $this->dirty[$id] = true; }}?> If you're wondering about the difference between a class and an object, in a building analogy the class is the blueprint and the object is the building. You can build several buildings from the same blueprint, they'll each be a different building but they'll all start from the same time. So a class is a definition of an object, and an object is a single instance of the class. Link to comment Share on other sites More sharing options...
Guest FirefoxRocks Posted July 19, 2009 Share Posted July 19, 2009 I'll read through the PHP guide on classes and objects, but there are some things I do not quite understand yet. Perhaps I'll check my local library for programming books. Or I'll wait until my computer programming class that I took in high school this year.What are the advantages of writing in object-based programming using classes? Less code? More secure? Faster code execution? Well-organization?And what does the minus less than stand for? Link to comment Share on other sites More sharing options...
Synook Posted July 20, 2009 Share Posted July 20, 2009 What are the advantages of writing in object-based programming using classes? Less code? More secure? Faster code execution? Well-organization?Better code re-usability, more flexible (e.g. can extend code instead of writing everything all over again), technically more secure due to encapsulation, can be better organised if used properly. Also helps with code logic. It is mostly about flexibility - the ability to apply a solution to several different problems, instead of writing something new for each of them. If something special is required, all you need a subclass.And what does the minus less than stand for?You mean "minus greater than"? It's PHP's member access operator, for accessing the properties and methods of an object (like JS's dot operator).A very interesting (abiet a bit old) book about applications for OOP is Design Patterns, by Gamma et al. (ISBN 0-201-63361-2). Link to comment Share on other sites More sharing options...
Guest FirefoxRocks Posted July 23, 2009 Share Posted July 23, 2009 Ok I found a video from Microsoft which explained a lot: http://msdn.microsoft.com/en-us/beginner/cc963989.aspxNow I just have to figure out how to use them and put it all together. Link to comment Share on other sites More sharing options...
boen_robot Posted July 23, 2009 Share Posted July 23, 2009 Ok I found a video from Microsoft which explained a lot: http://msdn.microsoft.com/en-us/beginner/cc963989.aspxNow I just have to figure out how to use them and put it all together.Hahaha.... hilarious!!! And you can bet those kinds (or at least some of them) are the kids of Microsoft employees ... talk about "the young generatinon" starting very early with programming.One word of caution though - PHP doesn't have "events", because the code runs line by line, until the sript is finished. C# and VB have events because one piece of code (e.g. downloading a file) may occur while the user is allowed to do other things (e.g. click a button to start another download, reexecuting the first piece of code at the event), and because the program may run until it decides to (typically until the close button is pressed). Link to comment Share on other sites More sharing options...
Guest FirefoxRocks Posted July 23, 2009 Share Posted July 23, 2009 Sorry I'm still confused here. Could I have some examples on how to use object-orientated programming (PHP) in each of the following things: Content management system Forum Calendar Photo gallery Link to comment Share on other sites More sharing options...
boen_robot Posted July 23, 2009 Share Posted July 23, 2009 OOP isn't used. It's being practiced. It's a way to program, not something that can do unique things on its own.In comparison, for example, being a vegetarian doesn't mean you'll stop global warming or anything, but does mean that you'll have a certain (presumably) healthier diet. You can have a healthy diet without being a vegetarian. The two are not mutually exclusive, but often happen to occur simultaneously non the less. Link to comment Share on other sites More sharing options...
Guest FirefoxRocks Posted July 23, 2009 Share Posted July 23, 2009 So would you recommend the use of OOP over procedural programming or vice versa? Link to comment Share on other sites More sharing options...
justsomeguy Posted July 23, 2009 Share Posted July 23, 2009 OO code is generally considered to be more maintainable and reusable than procedural code. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.