NotionCommotion Posted October 3, 2014 Share Posted October 3, 2014 I have a class which has two general types of methods. Those which are used by the core class, and shouldn't be overridden. Those which are "used" by the methods described above, and these can be overridden and new methods can be added. They are all private or protected, and not public. For those used by the core class, I use the "final" keyword to prevent. I am not really versed in namespace, but this seems like where it might be used. Could I get a couple of pointers where to start? Thanks Quote Link to comment https://forums.phpfreaks.com/topic/291416-help-with-namespace/ Share on other sites More sharing options...
requinix Posted October 3, 2014 Share Posted October 3, 2014 Namespaces? Something else entirely. Ever had a set of classes that are named similarly, like db_user/db_post or DatabaseUser/DatabasePost? You could use namespaces to help arrange the classes. Before: class db_user { } class db_post { } $user = new db_user(); $post = new db_post(); $user->post($post);After: namespace db { class user { } class post { } } namespace { use db\post; // so you can refer to it as "post" for short $user = new db\user(); $post = new post(); $user->post($post); } To your problem, final is exactly what you should be using. Quote Link to comment https://forums.phpfreaks.com/topic/291416-help-with-namespace/#findComment-1492621 Share on other sites More sharing options...
NotionCommotion Posted October 3, 2014 Author Share Posted October 3, 2014 Maybe it has nothing to do with namespace. Say I have the following script. I have a bunch of tasks, and I want to be able to extend the class and modify or add new tasks. It would be nice if I could add more tasks without having to worry about conflicting with one of the core methods. How would this best be handled? Thanks class myGeneralClass { //A core method which cannot be changed final public function doThis($method) { $this->$method(); } protected function task1(){} protected function task2(){} protected function task3(){} protected function task4(){} } class mySpecificClass myGeneralClass { protected function task1(){} //Overide protected function task5(){} protected function task6(){} protected function task7(){} protected function doThis(){} //Error! } $obj=new mySpecificClass(); $obj->doThis('task5'); Quote Link to comment https://forums.phpfreaks.com/topic/291416-help-with-namespace/#findComment-1492643 Share on other sites More sharing options...
requinix Posted October 3, 2014 Share Posted October 3, 2014 Keep in mind that the developer of the child class has to know about the parent class. You can simply push the "having to worry about conflicting" stuff onto the developer; as long as the parent class is locked down, make them figure out how their class should work. This task thing... can you explain it more? I feel like there's a better strategy to deal with it than creating more and more methods in a child class. Personally I avoid any situation where a parent class needs to call a specific, unknown child method without the child class somehow describing itself to the parent (eg, reporting that it has additional tasks 5-7). Quote Link to comment https://forums.phpfreaks.com/topic/291416-help-with-namespace/#findComment-1492645 Share on other sites More sharing options...
NotionCommotion Posted October 3, 2014 Author Share Posted October 3, 2014 This task thing... can you explain it more? I feel like there's a better strategy to deal with it than creating more and more methods in a child class. Personally I avoid any situation where a parent class needs to call a specific, unknown child method without the child class somehow describing itself to the parent (eg, reporting that it has additional tasks 5-7). My validation class. http://forums.phpfreaks.com/topic/291358-client-and-server-side-validation-passing-data-from-server-to-client/ I've created a method which does the same thing as every jQuery validation plugin method. Those are the tasks. Validate that a value is provided, validate that it is a valid phone number, etc. The main classes are Load Configuration JSON, Validate, Sanitize, etc. Quote Link to comment https://forums.phpfreaks.com/topic/291416-help-with-namespace/#findComment-1492650 Share on other sites More sharing options...
requinix Posted October 3, 2014 Share Posted October 3, 2014 Okay, but why are you using the subclasses to add methods? Overriding makes sense, sort of, with a validation class giving one implementation to a method and the sanitize class giving another, but they shouldn't be adding new methods into the mix. Your strategy is to model jQuery so as long as you do that then there shouldn't be any problems: the parent class will use methods with the same name, and the extending classes can't be adding new methods with the same names because that then wouldn't match the jQuery interface anymore. If you really do need to add methods, meaning that (for example) the base class can't validate phone numbers and you want to add that in with another class, then you have two options: 1. Add actual methods using traits. You'll define the functionality in one place, "add" it to the base class, and it will actually be executed as a real member of the base class. This is pretty much only about code reuse. 2. Make the code look like there are methods by using... I don't know the proper name but my boss calls it the "driver pattern". The base class transparently uses specific classes to provide the functionality that it seems to offer. More on the latter because that's what I think you're trying to get: Validation and sanitization (and whatever else you may want to do) is provided by one class per type. One class covers phone numbers, one class covers integers, etc. It then implements a "validator" interface which declares methods for validation and sanitization (and whatever). interface IJqValidator { public function validate($value); public function sanitize($value); } class PhonenumberValidator implements IJqValidator { // lowercase 'n' public function validate($value) { // validate the phone number } public function sanitize($value) { // sanitize the phone number } }Your base class then goes hunting for that class when needed. class JqValidator { private static $validators = array(); private static function getValidator($type) { if (!isset(self::$validators[$type])) { // $type="phonenumber", $class="PhonenumberValidator" $class = ucfirst(strtolower($type)) . "Validator"; self::$validators[$type] = new $class(); } return self::$validators[$type]; } // the implementation here could go a few ways // 1. ->validate(type, value) public function validate($type, $value) { return self::getValidator($type)->validate($value); } // 2a. ->type->validate(value) public function __get($name) { return self::getValidator($name); } // 2b. ->type()->validate(value) public function __call($method, array $args) { return self::getValidator($method); } // 3. construct the class with a mode, validate/sanitize, and then use ->type(value) const MODE_SANITIZE = "MODE_SANITIZE"; const MODE_VALIDATE = "MODE_VALIDATE"; private $mode = ""; public function __construct($mode) { $this->mode = $mode; } public function __call($method, array $args) { switch ($this->mode) { case self::MODE_SANITIZE: return self::getValidator($method)->sanitize($args[0]); case self::MODE_VALIDATE: return self::getValidator($method)->validate($args[0]); } } }I personally don't like #2 or #3 because there's no autocomplete support and I have a philosophy that if I can't get IDE support for something then it is probably a bad idea and needs to be done differently. Fortunately, I'm guessing that #1 wouldn't be a problem based on how I think you're using the rest of the code. Quote Link to comment https://forums.phpfreaks.com/topic/291416-help-with-namespace/#findComment-1492653 Share on other sites More sharing options...
NotionCommotion Posted October 4, 2014 Author Share Posted October 4, 2014 Thank you Requinix, Okay, but why are you using the subclasses to add methods? I didn't think I was. Please let me know why you feel so. Overriding makes sense, sort of, with a validation class giving one implementation to a method and the sanitize class giving another, but they shouldn't be adding new methods into the mix. I decide to add a new method to the jQuery validition plugin which validates that the input is a given Yiddish word. Unfortunately, my PHP class doesn't have this validation function, so I will need to add it to it as well. Your strategy is to model jQuery so as long as you do that then there shouldn't be any problems: the parent class will use methods with the same name, and the extending classes can't be adding new methods with the same names because that then wouldn't match the jQuery interface anymore. Again, no Yiddish. ...then you have two options: Haven't dived into it yet, but I expect I don't I like Option #3, and dislike option #2 even more. Please let me give this more thought. Validation and sanitization (and whatever else you may want to do Oh yea, I forgot. A big one is create the JavaScript object which is used by the jQuery validation plugin, but I think/hope I have that one covered. ... is provided by one class per type. One class covers phone numbers, one class covers integers, etc. It then implements a "validator" interface which declares methods for validation and sanitization (and whatever). I am lost. Probably me, but please elaborate Quote Link to comment https://forums.phpfreaks.com/topic/291416-help-with-namespace/#findComment-1492662 Share on other sites More sharing options...
requinix Posted October 4, 2014 Share Posted October 4, 2014 I didn't think I was. Please let me know why you feel so.Then I misunderstood. Nevermind. I decide to add a new method to the jQuery validition plugin which validates that the input is a given Yiddish word. Unfortunately, my PHP class doesn't have this validation function, so I will need to add it to it as well.Yeah, that's what I'm getting at: having to add a new method every time suggests using a different coding strategy. Again, no Yiddish.Then vice versa: the parent can't possibly have a "yiddish" method because jQuery doesn't, but a subclass could. Either the parent will have the method and the children shouldn't, or a child will and the parent shouldn't, but both won't have it. Oh yea, I forgot. A big one is create the JavaScript object which is used by the jQuery validation plugin, but I think/hope I have that one covered.That would be a third method to add to the interface: a way of serializing the requirements or behavior or whatever. Preferably you'd stuff some information into an object and then code can serialize (via the JsonSerializable interface and json_encode(), for instance) the class's data into the Javascript. I am lost. Probably me, but please elaborateIt's describing what I did in the first bit of code: one class (PhonenumberValidator) per type (a phone number) that implements an interface (IJqValidator). You could have another class (EmailValidator) per type (an email address) that implements the same interface. class PhonenumberValidator implements IJqValidator { // lowercase 'n' public function validate($value) { // US number: 3+3+4 = 10 digits // as a courtesy, strip common separators transparently. sanitize() will remove them again later $value = preg_replace('/[-(). ]/', '', $value); return ctype_digit($value) && strlen($value) == 10; } public function sanitize($value) { // strip everything but numbers return preg_replace('/\D/', '', $value); } } class EmailValidator implements IJqValidator { public function validate($value) { return $this->sanitize($value) === $value; } public function sanitize($value) { return filter_var($value, FILTER_VALIDATE_EMAIL); } } Quote Link to comment https://forums.phpfreaks.com/topic/291416-help-with-namespace/#findComment-1492665 Share on other sites More sharing options...
NotionCommotion Posted October 4, 2014 Author Share Posted October 4, 2014 (edited) Ah, I now see you you are creating a file with a separate class to validate and sanitize each given thing. If one wanted to add a new method, they would add a new file with a new class for the given thing, right? I was planning on creating a single class which includes core methods as well as all validation methods and sanitation methods. If one wanted to add a new method, they would just extend that class and add the method. I probably see the advantage of your approach, but please confirm you feel it is the right way to go. Below is my total implementation. The validation class is attached (tried to add to this post, but must have been too long and didn't format correctly). I realize it is a bunch of script and don't expect you to go through it all, but would appreciate any comments. Thanks Main page <!DOCTYPE html> <html> <head> <script type="text/javascript" src="jquery.js" /></script> <script type="text/javascript" src="getValidationObj.php" /></script> <script type="text/javascript"> (function() { $("#myForm").validate(validation_JSON); }); </script> </head> <body> <form id="myForm"> <input name="name" type="text" /> <input name="email" type="text" /> </form> </body> <html> getValidationObj.php Note that I know Jacques1 said not to use PHP to generate JS, however, I don't know a workaround. Yes, I could create JSON instead, however, the client would on same cases need to use eval() which is also not ideal <?php header('Content-Type: application/javascript'); $config_file='/path/to/aGivenPagesValidationFile.json'; $modify_file=array('isNameRequired'=>true); $validate=new validate($config_file,$modify_file); exit("var validation_JSON ={$validate->getJSON()};"); ?> aGivenPagesValidationFile.json { "rules": { "name": "{isNameRequired}", "email": { "required": true, "email": true } }, "messages": { "name": "Please specify your name", "email": { "required": "We need your email address to contact you", "email": "Your email address must be in the format of name@domain.com" } } "sanitizers": {} } Script to save data <?php $config_file='/path/to/aGivenPagesValidationFile.json'; $modify_file=array('isNameRequired'=>true); $validate=new validate($config_file,$modify_file); $data=$validate->sanitize($_POST); $errors=$validate->validate($data); if(empty($errors)) { //Save the data } ?> validate.php Edited October 4, 2014 by NotionCommotion Quote Link to comment https://forums.phpfreaks.com/topic/291416-help-with-namespace/#findComment-1492708 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.