Jump to content

deadimp

Members
  • Posts

    185
  • Joined

  • Last visited

    Never

Everything posted by deadimp

  1. Explicitly scoping a method call to a class can be used in inheritance. Say you're overloading a parent's method in a child class, but you want to still use the parent method in your child's method. If you try calling that same method as you normally would, you would just get a infinite recursion (probably resulting in stack overflow). But if you explicitly scope the method call (inside the class), the interpreter knows to call the parent's function. Example: <?php class Dad { function format($str) { return "[ $str ]"; } } class Child extends Dad { function format($str) { //Calling $this->format($str) would call this same function, but scoping it to the parent will not return "{{ " . parent::format($str) . " }}"; } } $timmy = new Child(); echo $timmy->format("something"); ?> It's like explicit scoping in C++ in that you don't put the $this-> reference (since you can't, i.e. $timmy->Dad::format("something") is apparently illegal). You call it as you would a static, but it still retains the $this reference - which can create problems with other functions if you don't declare them as 'static' functions... but that goes along with coding practices as 448191 pointed out. Probably more than you wanted know. Meh.
  2. The DNS for deadimp.org should be working now - I don't know why there would be a DNS error. Kind of a late response. And to add something slightly random, Thacmus is now on SVN, so it should be easier just to browse the current source.
  3. Throwing my own stuff out there: Thacmus Tutorial: Form (old, but still applies - too lazy to update...) You can view the source under Source, thacmus/lib/field/* (the files in there). You certainly don't have to use it, certain things you may like / hate.
  4. You could clean it up some, making $class the only variable that controls what the CSS class will be (outputting it at the end): $radio=?; //What is radio? Couldn't this apply to any field / form element? $class=''; if (is_array($extras)) { $check=array('text','position','class'); //This is a little less efficient that the way you have it below, but a little more flexible. foreach ($extras as $key => $value) { if (!in_array($key,$check)) $radio=" $key=\"$value\""; if ($key=='class') $class=$value; } } if ($this->hasError) { if (array_key_exists($name,$this->errors)) $class.=' form-radio-error'; else $class=''; //Don't add anything else? } $class=trim($class); //Get rid of the extra whitespace - OCD on formatting if ($class) $radio.=" class=\"$class\""; There's alternate ways to change it. You could just have all of the field's attributes controlled by the array $extras, and on errors have it manipulate the element 'class' (adding it if it doesn't exist) in that array. That might be a little more flexible, and you could divide some of the functionality with that. Now, what's the point of having it specify 'text' and 'position'? 'text' would just be 'value', and I really don't know what 'position' could be. You could have a sub-array/string in that one array that's style, which either lists the attributes in an array or string. Ex: $extras=array( 'name'=>'bob', 'size'='10', 'value'=>'Awesomeness', 'style'=>array( 'text-align'=>'left', 'margin'=>'16px') ); Applying your own formatting, of course.
  5. See how you yourself program and use this API. If you find yourself writing out repetitive insert / update / delete / whatever statements in 'raw' queries, you might want to make a wrapping function for it. If you're going to make this adaptable for multiple database drivers / types / whatcha-call-it, keep in mind that there may be functional differences in how they operate, especially in query syntax.
  6. The PHP Manual on OOP is a great resource. Nice 'n free.
  7. Those only do the same thing if they're called in the scope of the class, or if you simply don't make any references to $this (instance level members/methods). Static scope, in a simple sort of way, means that the data is the same for all instances (instances are objects instantiated with new) - it's stored 'in the class' as opposed to in the instance Say if you have two instance of lyrics, say 'bob' and 'george', and you only refer to static members with the methods, '$bob->func()' and '$george->func()' will do the same thing as 'lyrics::func()' (where 'func' is any function you have defined) - meaning you don't even need those two instances. This is a situation you would NOT want. With simple OOP, you can organize and separate data a little better. Here's just an example: class Person { public $name, $age; function __construct($name,$age) { //Instance level - this is the function called for new Person(...) $this->name=$name; $this->age=$age; } function func() { //This function is instance-level - References to $this means it gets data from the instances, so it can be different per instance echo "Person: $this->name - $this->age<br/>"; } } $bob=new Person('Bob',26); $george=new Person('George',24); $bob->func(); $george->func(); Output: Person: Bob - 26 Person: Geroge - 24 Also, reading the manual will do a lot more for you than me just making up random examples.
  8. Two things: 1. You're trying to set the default argument ( function pageContent($html=$echo...) ) by referencing to something out of the constant scope. In short, you can't do that. What you could do, if you want to keep with your design, is have it null by default, check in the function, and set it by checking if it's null. Example: function pageContent($html='') { if (!$html) { global $echo; //Include the global $echo in the scope - This is if the script is executed in the global level - VERY iffy in this context $html=$echo->html; } return $html; } To be honest, that design is a little odd, for lack of a better word. You could do something more like this (assuming that pageContent() is only called once, which it should be): function pageContent() { //Changing a few things - read the next point $obj=new lyrics(); //Generic name - a little better than just $echo if (!isset($_GET['lyrics'])) $obj->search(); //Not static else { $obj->grabInfo(...); $obj->getThisEdit(); //And so on... } $obj->generateHTML(); //Wouldn't you want this for either case? return $obj->html; } 2. Why do you use static methods (i.e. lyrics::search()) in this sense? They look like they use instance-level data... You might want to go over the OOP Section and look at methods once more.
  9. http://www.php.net/manual/en/language.oop5.php It looks like you're trying to find a way to call a parent's method. If it isn't defined in the child class, you can simply call it as $this->blarg(). If blarg() is overloaded (right for polymorphism terminology?) in the child class, you can explicitly call the parent's method using parent::blarg() inside child::blarg() - though you can't explicitly call the parent's method from a child object outside an object's method scope. If you're sure of your design, and you want to use that explicit calling stuff, here's an example: class Base { //Example with ctor public function __construct() { echo "Base::ctor\n"; } public function bleck() { echo "Base::bleck\n"; } public function test() { echo "Base::test\n"; } } class Child extends Base { public function __construct() { parent::__construct(); //Explicitly call parent's ctor method //Do your own stuff here echo "Child::ctor\n"; } public function bleck() { $this->test(); echo "Blah"; } } $obj=new Child(); $obj->bleck(); /*Output: Base::ctor Child::ctor Base::test Blah */ Just so you know, every class inherits stdClass. Unless making your own base object for your system is a dire need, use what PHP already has. Also, what's the reason behind manually setting a reference in an object to itself? That's the exact reason for the the $this keyword.
  10. It would be better to use the __construct keyword because PHP does not warn you when the class's top-level constructor is explicitly called. I ran into this problem a while back while using the class name, which caused me to switch to using the keyword. I had a parent class which defined an update() method, and had several classes inherit from it. One of my classes ended up being named Update, and I had defined the constructor as Update(). I realized my problem (after a long time) after trying to update the object via the parent's update() and seeing that all it did was reinitialize the variables.
  11. To verse yourself in the basics of OOP in PHP, the manual is an invaluable resource. For myself, I learn best primarily through example. The manual provides simple samples along with explanations of how they work. I never got a book myself, so I can't suggest one off the top of my head. In addition to the manual, of course, you can look at other open source projects and see how they might do things. [OOP in PHP is somewhat similar to Java's as far as referencing goes (and maybe a few similar keywords), but after that they do a few things differently - the languages themselves are different] In case you don't already have one, get a test server to mess around in. I'd suggest XAMPP to start off with - make sure that the server has PHP 5 (the PHP 4 end-of-life was a few months ago). Make yourself a 'sandbox' directory, and just start coding. If you see an interesting example, copy and paste it, run it. Next, just mess around with it. Make something random, make something useful, it doesn't really matter since you're in the learning stage. In fact, it would probably be best just to try out the random stuff. The more specific stuff can be found through googling for php tutorials.
  12. Well, not exactly. My design is a little different from most others, in that the actual connection information isn't stored in an object (something instantiated by new), but instead as statics in the database interface class. [i probably should change this later on... The fact that I can't explain this well is kind of a bad sign ] The classes from the Thacmus framework for this portion of code: DBI [ /db/dbi.php ] - The static members / variables store the overall connection information. From there, each class that needs access to store information about itself in the database implements this class. As you can see, Department has to store information about itself, so it extends the DBI class (inheritance, polymorphism). The DBI class defines the base functionality for direct interaction between the database, i.e. querying the database and storing the information in the right variables / members, sending an insert / update query to save data, all the while escaping the data to prevent injection attacks. The readAll() method is an example, which specifies a condition to work off of, such as actual conditions ('[=condition]' which is expanded to "`condition`='yes'"), pagination (ex 'limit 0, 50'), sorting ('order by `column`'), and so on. Field [ /lib/field/main.php ] - Specifies a general way to handle data through, well, fields - how to take input and give output, render the field with a certain value, etc. The heavy amount of abstraction in the Field allows it to easily interact with Form, handling the data for an object, which in effect makes it easier for Editor [ /lib/editor.php ] to handle database objects. FieldCombo [ /lib/field/common.php ] - Extends FieldList (in same source file), which extends Field. These specify how to handle a list of data. The only real difference between FieldCombo and FieldList is that $size is 0, which makes the 'size' attribute of <select> 0, which turns it into that combo box. Most of this can be found in the Tutorials section. I'm probably typing too much now. In this case, the SQL query for the database instance isn't actually an object. It's just used in the database instance, which in this case is $temp, an instance of Department. The call to $temp->readAll() uses the information in the object itself, the $temp dummy, to determine what class it is and the table information. From there, it queries the table specified in the highest-level static of $table (which in this case will resolve to 'table') with the attached conditions, reads all of the result rows into new Department objects, which are pushed onto the array $list. I apologize if the terminology is a little too heavy. If you need to know what something is, just ask. Also need to make a correction in my previous post's code: //For the combo box: $data=array(); foreach ($list as $obj) $data[$obj->id]=$obj->name; $combo=new FieldCombo('department',$data); Before I had the combo's take in data from the objects themselves, which didn't make sense. Now this gives the combo a list that associates the object's id (corresponding to its row in the table) to its name. This, of course, assumes that the table structure has the autoincrement column `id` defined (according to the design for DBI). Plus, since so little data is used in the query, it might be a little more efficient to specify which columns are needed ('select `id`,`name`'). Hmm, at the moment the servers are down at the moment. Should be up within a little while. To download the source code: http://sourceforge.net/projects/thacmus/ EDIT: It's up now.
  13. "Turning something into OO" is kind of an abstract concept. I'm guessing you're asking how to incorporate OOP into your design. There's many ways you can do it, and here are a few: Use the mysqli extension so that you can access your MySQL databases using an OOP design. Abstract your database access so you can plug in drivers for other engines (like PostgreSQL). Use some sort of form-building library to make your combo box for you, possibly making an easy-to-establish 'connection' between your database driver and your combo boxes. And to add the usual response: You can get a lot if you look at a few of the frameworks and CMSes out there, not just concerning OOP but general application design. Some may fit your tastes, some may not. To name some of the popular ones: Drupal, Joomla, MediaWiki, CakePHP, CodeIgniter, TangoCMS. The list goes on. A design pattern that most of them seem to incorporate is MVC, something you may want to look into too. Here goes the plug: I'm developing Thacmus, a small framework/CMS, aiming to keep it simple. I wouldn't say that it comes anywhere near the applications listed above, but it could also give you some insight (it might or might not be bad influence concerning my practices...). To do what you had there, this is an attempt in Thacmus (didn't really test it...): //Define database class class Department extends DBI { public $name, $code, $condition, $apricot; static $table='table', $db_var=array('name','code','condition','apricot'); } ... //Get and render the list $list=array(); $temp=new Department(); //Use a 'template' class $temp->condition='yes'; $temp->readAll($list,"where [=condition] and length(`code`)=3 order by `apricot` desc"); //Uses query formatting - also put length condition into query to simplify things //Scan list //Create comob $combo=new FieldCombo('department',$list); $input=//Whatever you may get from $_GET or $_POST echo $combo->render($input); Other people / frameworks / CMSes do it their own way. It's just an option.
  14. Are you making sure that PHP is running as a CGI module? I think if you do that then PHP will automatically parse the query string and delegate it to all of the superglobals. However, I haven't dealt much with manually setting up my own server, and I'm not that familiar with the down 'n dirities of PHP.
  15. To specify over what aschk and Daniel0, you can use the Reflection API to instantiate your class using a varying number of arguments as you would with call_user_func(). I'll leave it up to you to find which function that is in the manual. And backing what Daniel0 said, overloading is convenient for a strictly-typed language. You should have some sort of an idea about which type your variable is that you're handling, therefore you should know what you're doing with your functions, be they operators or the general kind.
  16. It's true that it isn't great in all circumstances, just with almost every other convention that may be used. However, dynamic forms can be more of a convenience if you have a large volume of generic forms which may handle large amounts of data. In that case it might be a little difficult for your XHTML designer - they have to make sure that if the form maybe used for 'revision' (editing), it would need to be auto-filled. Adding to that, say you have a combo box with large amounts of dynamic data - would a static html file be the best solution? The XHTML designer would have to either learn PHP to insert the data - doubt he'll want to learn how to sanitize and all that - or a templating system that you would use - which could be a good or bad idea, just depending on what it is (maybe Smarty could do it much better). Plus, it should be a relatively simple cut-and-paste effort to add new generic fields to a form. If you want a new text field with the name "bob", just type out "$form->addText('bob')" or for another implementation add "new FieldText('bob')" to the field array. If you're working on a team, you should be able to work together. Use the XHTML designer's knowledge to make the generic HTML output for your form, and leave it to yourself or your PHP coder(s) to work that into the form system. On the other side, there are times where custom-designed forms are a good idea. The form system you have in place should have an open, clear-cut way to split processing from form rendering just in case. MVC would be a good option, and so would a simple division between processing and output (though it could be more error prone ).
  17. If you want guidelines on a form system, try looking at different frameworks or CMS's to see how they handle theirs. Most form systems are similar to what able posted, with maybe a few differences. Just google "php framework" or "php cms" and you should find the popular open source projects. From there you can just browse the code. There's also Thacmus, a project I'm working on, which has a pretty basic form system in place. You can browse around the form system's source in /lib/field, and the files you'll want are main.php, common.php, and form.php. Along with all that, I have a Form tutorial. It deals with a previous version, so some of the information isn't accurate (I need to update that soon), but the basic concept is explained there. NOTE: The source is read from files on the server, so it isn't exactly a code repository. You'll probably want to download the source if you want to browse more than a couple files. If the site is slow or down, just go to the SourceForge page. [/shameless plug]
  18. [shames himself for going off topic] Yeah, that whole static/instance hybrid design isn't the best implementation known to man, but it is the best implementation I've been able to think of. However, I figured that since certain classes have raw data that is retrieved from the database and put right into the class, I decided to skip a few steps and had the database directly interface to the class. My [kinda messed up] thinking on that: DBI -> DataBase Instance -> instance that interacts with the database. I may be wrong, but I was looking through RoR and I think I saw kind of the same thing, except that the class declared it's database variables using field information rather than having it defined statically as I do.... I don't know because I haven't played around with RoR - which I need to. Of course, RoR is MVC, and mine is... well, nothing really standard (as I know). I feel the next version is a hell-lot better organized than the current one (though it's still kind of a mess) so it might be a little easier to browse, too. Glad to see someone interested in it!
  19. To elaborate, the eval() call that thorpe was talking about is most likely made inside of a function scope, meaning that $life would be a local variable to that function and wouldn't be a global, as you found out.
  20. Is using the -> operator on an expression (not a variable) always illegal? Or am I doing something wrong? Ex. class Test { var $var, $extra; function __construct($var) { $this->var=$var; } //Allow variables to be set right off of a class, returning this for chaining - like jQuery or whatever else there is function extend($extra) { $this->extra=$extra; return $this; } } $bleat=(new Test("biscuit"))->extend("super-something"); Throws: "syntax error, unexpected T_OBJECT_OPERATOR" I know you can do this in C++ and Java, due to their 'type parametric' nature, and I assumed it would work with PHP. Info: PHP 5.2.5, XAMPP, WinXP I guess I'm gradually growing more disappointed in some of PHP's non-flexible syntax. I'm not sure whether it's just a design flaw, or a design scheme meant to force 'cleaner' code. EDIT: One ugly workaround: function& w(&$x) { return $x; } $bleat=w(new Test("biscuit"))->extend("super-something"); NOTE: There's no point to this impelmentation. It's meant for demonstrating.
  21. Find a CMS or a framework and see how they do it. I have one in Thacmus: /db/user.php However, I haven't released a new version in a few months (but I plan to in a week or so). The user system I have is kind of weak, not exactly in security, but in structure. Also, the stylesheets are broken (will be fixed within the new release). In the newer version, there's a little more cohesion to manage permissions and all that better, especially with the basic implementation of user groups and such.
  22. The best solution for this would be something in the Reflection API, more specifically, ReflectionClass::newInstanceArgs(). Just implemented something using this not too long ago. You'll need PHP 5 for this, though. If you're using PHP 4, I don't know what to say really, other than just try to use eval().
  23. I guess it would depend on the security that you impose on the devices that control these objects. [Heh, that sounded fancy] It boils down to context. There's places where it wouldn't much matter, and others where it could possibly kill the script/system. If you are careful and sanitize and limit the user's input there shouldn't be a problem. If you haphazardly sling together code into some sort of spaghetti-structured mess, you'll be in for a ride. Example of insecure code: <form action='this.php' method='post'> <input type='text' name='name' value='Bob><br> <input type='text' name='age' value='82'> </form> <? //Data class User { var $name, $age, $pass, $level; function __construct(...) { } function update() { ... Update user info in database ... } } $bob=new User('Bob',82,'flapjacks',User::Common); //Let's say User::Common==1, User::Admin==3 //Processing input foreach ($_POST as $var => $value) { $bob->$var=$value; } $bob->update(); ?> Seems harmless, until someone comes along and injects some HTML in your form, say something like "<input type='text' name='level' value='3'>" and has it process it. As for efficiency, once again, it depends. I doubt it'll be too much of a burden unless you decide to use variable variables the whole time, but even then it shouldn't be that bad. PHP is designed to be a dynamic language.
  24. It is possible to get PHP to parse your string using eval(), but emehrkay's solution is much cleaner, faster, more secure, etc, meaning there's no reason to use this in this circumstance.
  25. Ran into the same problem: http://www.phpfreaks.com/forums/index.php/topic,152955.0.html However, if you're into interfaces, you can have one class implement multiple interfaces. interface Honest { function etc(); } interface Rock { function stuff(); } class Frankenstein implements Honest, Rock { function etc() { echo "blerg\n"; } function stuff() { echo "blarg\n"; } } $obj=new A; $obj->etc(); $obj->stuff(); Of course, you can't put any meat into your interface method declarations...
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.