Jump to content

NotionCommotion

Members
  • Posts

    2,446
  • Joined

  • Last visited

  • Days Won

    10

Everything posted by NotionCommotion

  1. I have the following method. As you can see at the bottom, it calls itself and is recursive. Question is whether I should pass the current scope when I recursively call the method, or in the interim, store them in $this. I am assuming that I shouldn't use a static variable, right? Currently, I am storing the interim data in $this and adding to it every time the method is executed (for instance $this->realPoints[$point->id]=$point;), I have two concerns. First, it would make more sense to me if it returns the values instead of setting something which would later need to be requested (Reference http://forums.phpfreaks.com/topic/301316-should-methods-typically-return-multiple-objects/). Also, if the method is called twice outside itself, it gets doubled which is not my intent. Or should recursive functions explicitly have earlier data passed to them? For this case, I require realPointIDs, realPoints, cacheReal, aggrPoints, aggrPointIDs, cacheAggr, custPointIDs, and custPoints. Or should this single method have it's own class? I am thinking this might make the most sense. Any thoughts? Thank you private function _setPoints(array $items, $byName=false) { $model=$this->getModel(); $custPoints=[]; $points=$model->getPoints($items, false, $byName); foreach($points as $point){ if($point->type=="real" && !isset($this->realPoints[$point->id])){ $this->realPointIDs[]=$point->id; $this->realPoints[$point->id]=$point; if($this->cacheReal && $point->timestamp < $this->time-$this->cacheTimes['real_points']) { $this->cacheReal=false; } } if($point->type=="aggr" && !isset($this->aggrPoints[$point->id])){ $this->aggrPointIDs[]=$point->id; $this->aggrPoints[$point->id]=$point; if(!isset($this->cacheAggr[$point->duration.'~'.$point->offset]) && $point->timestamp < $this->time-$this->cacheTimes['aggr_points']) { $this->cacheAggr[$point->duration.'~'.$point->offset]=true; } } if($point->type=="cust" && !isset($this->custPoints[$point->id])){ $this->custPointIDs[]=$point->id; $custPoints[]=$point->id; } } if(!empty($custPoints)){ $customNew=[]; while($custPoint=$model->getCustomPoints($custPoints)){ //$this->custPointIDs[] already set $id=$custPoint->points_custom_id; unset($custPoint->points_custom_id); $this->custPoints[$id][]=$custPoint; $customNew[]=$custPoint->points_id; } $this->_setPoints($customNew); } }
  2. That is what I was implying under: catch (USERException $e) { //Deal with the error } Thank you all three for your replies. Okay, I concede using exceptions for validation isn't best. I heard the word "exceptional" behavior and situations a couple of times. I thought exceptions are used to deal with user behavior, and errors are used to deal with bugs in the script. What do you consider is exceptional?
  3. Consider the following. Also, please comment on my use of USERException. Thanks <?php try { $validate=new Validate(); $data=$validate->getValidatedData($_POST); //insert record } catch (USERException $e) { //Deal with the error } //New file class USERException extends Exception {} //Should this exception be defined here? Should another exception type be used? class Validate{ public function getValidatedData($data) { if(!isset($data['city'])){throw new USERException("City field is missing.");} if(!$this->isACity($data['city'])){throw new USERException("$data[city] is not a valid city.");} // ... return ['city'=>$data['city'],'etc'=>123]; } } ?>
  4. Thank you requinix, You point about whether a point mutates make sense. Thank you Jacques1,Your replies were helpful.
  5. I am just starting to think about this, haven't attempted to do anything with it, and unfortunately do not have any real examples. Okay, I see what you mean about deciding between a single getter and multiple getters depending on how the data is related, and there is no way anyone could answer without more details. Does a setter just set some property inside the object? Are PDO::prepare() and PDO::execute() setters, and PDO::fetch() a getter? If a setter is first executed, is it typically considered better practice to access the property directly, or through some method (which is a getter?) which then returns the property? Does a setter typically return the object (i.e. return $this;)?
  6. For instance, I can do this. $o=new MyObj(); $stuff=$o->getStuff(); $a=$stuff->a; $b=$stuff->b; $c=$stuff->c; Or should I do this? $o=new MyObj(); $o->setStuff(); $a=$o->a; $b=$o->b; $c=$o->c; Or maybe this? $o=new MyObj(); $a=$o->getA(); $b=$o->getB(); $c=$o->getC(); If one of the latter two, should setStuff() return $this so I can chain it? $a=$o->setStuff()->getA(); I recognize every situation is different, and am just looking for typical best practices. Thanks
  7. Is chaining methods considered good or bad practice? Please explain why or why not. If it is considered okay, please provide recommended formatting. Thanks return $db->prepare("SELECT a, b, c FROM mytable WHERE id=:id") ->execute(["id"=>123]). ->fetchAll(PDO:FETCH_OBJ);
  8. Thanks Jacques1, For now, I just wrote my own router. One of these days, I will start using a framework, and am sure one is built in, so why get married to another. I would expect the Apache rewrite engine is significantly faster and maybe will save a billionth of a second. Glad I am not the only one who thinks it is a PITA, and I will concede this small performance advantage for less pain.
  9. Ah, that is exactly what I want. Thanks! Do you have any recommendations? Have you tried any of the following? https://github.com/mrjgreen/phroute https://github.com/dannyvankooten/AltoRouter https://github.com/dannyvankooten/PHP-Router http://blogs.shephertz.com/2014/05/21/how-to-implement-url-routing-in-php/ http://www.kratedesign.com/blog/2010/03/php-router-and-clean-urls/ Yes, compared to the Apache rewrite engine.
  10. I was going to say something needs to be done in code. Maybe combining the composite key strings as a single unique property name. But then I read more on maxsd's link. ORM? Yea, I've heard of them, and they are on my list of things to learn up on..... If my question was posted before ORM's existed, would it make more sense?
  11. I recently tried http://www.slimframework.com/ to set up a REST API. Easy. Is there any reason I should use it or some other similar product for a normal website navigation? Previously, I put complicated (at least to me) regex in my httpd.conf (or .httacces) files to make URLs pretty. The redirects when using Slim is just to send everything to index.php if it isn't real. Yea, I am sure if volume is high, it isn't ideal, but what about when just starting off? Thanks
  12. Well if it doesn't make sense to you and Jacques, then it probably doesn't make sense to me either! Not really a search. Say I have $obj and $obj has properties "somePrimaryKey1", "somePrimaryKey2", and "somePrimaryKey3", I can access them by using $obj->somePrimaryKey1, etc. Turns out $obj wasn't created from a class, but was created from a database and PHP script. Maybe this is why it doesn't make sense. Is doing this unheard of?
  13. I first thought about this based a previous post where I wanted to identify based on a min and max range. It seems more interesting, however, when applied with relational databases. I don't think it is too uncommon to make a collection of entities using some single primary key as the object name and other columns as the object's properties. I then can identify a member in the collection by using $obj->somePrimaryKey (or maybe some derivative of the PK). But, how can the member be selected if that primary key was a composite? PS. Some of my OOP terminology might be off as I never new the term "collection" before now.
  14. In SQL, two (or more) keys can be used to positively identify a record. How can this concept be used regarding an object's property name?
  15. After giving it more thought, it is the ranges that are giving me problems. For instance, let's say the client wants the following. maximum freezer_1_temp starting zero years ago (0 s) for a duration of three years (94608000 s) minimum freezer_1_temp starting zero years ago (0 s) for a duration of three years (94608000 s) maximum freezer_2_temp starting zero years ago (0 s) for a duration of three years (94608000 s) maximum freezer_1_temp starting one year ago (31536000 s) for a duration of four years (126144000 s) One option is that I could send the data described under SENT, and receive the data described under RECEIVED. While I like this from an object perspective, I really don't like how I am concatenating the ranges to make a property name. But what else could I do? Another option is I send the same thing (an array with 4 elements), and I return [40, 20, 20, 30]. But this means that the order of the sent and return data identifies each. I don't know why, but I just feel one shouldn't do so. SENT Array( [0] => stdClass Object ( [param] => freezer_1_temp [fnc] => max [range] => Array ( [0] => 0 [1] => 126144000 ) ) [1] => stdClass Object ( [param] => freezer_1_temp [fnc] => min [range] => Array ( [0] => 0 [1] => 126144000 ) ) [2] => stdClass Object ( [param] => freezer_2_temp [fnc] => max [range] => Array ( [0] => 0 [1] => 126144000 ) ) [3] => stdClass Object ( [param] => freezer_1_temp [fnc] => max [range] => Array ( [0] => 31536000 [1] => 126144000 ) )) RECEIVED stdClass Object( [freezer_1_temp] => stdClass Object ( [0_126144000] => stdClass Object ( [max] => 40 [min] => 20 ) [31536000_126144000] => stdClass Object ( [max] => 30 ) ) [freezer_2_temp] => stdClass Object ( [0_126144000] => stdClass Object ( [max] => 20 ) ))
  16. I must apologize to you, Psycho, and ginergr. I thought a generic situation would be more relevant to others, but I can't seem to communicate the issues. Please let me start over. Multiple real-time monitored parameters (i.e. freezer temperature, freezer power, etc) are being stored on 15 second intervals with history which might span over many years. I need to create an API to query the data which is based on the following: The parameter being monitored such as freezer #1 temperature. An aggregate function on the parameter such as the minimum, maximum, sum, weighted sum, count, average, etc. A MaxTime > time > MinTime WHERE statement. This constraint will actual be something like "from X seconds ago and going back Y seconds". The client will typically ask on ideally a single request "Give me maximum and minimum temperature of freezers #1, #2, and #3 from one year ago to three years ago, minimum temperature of freezer #3, #4 and #5 for those same time spans, and average temperature of freezers 2 and 5 but between today and 4 years ago." The queries might be expensive, and should be optimized. We don't have total control over the clients request, and would like the server to have some control over its own destiny. I recognize I haven't provided the database schema which makes any definitive answers impossible, but.... How should the client request the data and the data be returned so that the server could optimize the queries and the client be able to identify the returned results?
  17. Thanks Psycho and ginerjm, Originally, I was thinking that the client should provide the request from their point of view, and let the server deal with optimizing the queries. I was also thinking of returning a given aggregate function only if the client needed it, but it definitely simplifies things to return all regardless of whether requested (for instance, I wasn't requesting MIN of Item "a", but it is not a big deal to send it anyways). For instance: Sent: [{"item":"a","fn":"SUM","limit":123},{"item":"a","fn":"MAX","limit":123},{"item":"b","fn":"MIN","limit":123},{"item":"a","fn":"SUM","limit":321}] Received: [{"john":140,"Mary":120}, {"john":18,"Mary":12}, {"john":4,"Mary":6}, {"john":240,"Mary":320}} This would require identifying the request with the reply based on each's position in the array, and I was concerned that doing so was a bad idea. Or, I could require that the client structure it, and do something like the following (still need to deal with the limit 321): Sent: {"item":["a","b"], "limit":123} Received: {"a":[{"john":{"MIN":4,"MAX",18,"SUM",140}}, {"mary":{"MIN":6,"MAX",12,"SUM",120}}, "b":["john":{"MIN":4,"MAX",12,"SUM",240}},"Mary":{{"MIN":6,"MAX",22,"SUM",420}}} or Received: {"a":{"john":{"MIN":4,"MAX":18,"SUM":140},"mary":{"MIN":6,"MAX":12,"SUM":120}},"b":{"john":{"MIN":4,"MAX":12,"SUM":240},"mary":{"MIN":6,"MAX":22,"SUM":420}}}
  18. Thanks ginerjm, What you are saying makes sense. I just don't seem to have any such key. I suppose the client could generate a surrogate for no other purpose other than send it with the request, and then the server could use it to label it for the way back. Is doing so typically done? Or I could maybe hash the request and use that as the key?
  19. Let's say a REST client needs four pieces of information. It could do it in four requests, and when it receives the data, it knows it is associated with what was requested. Sent: {"item":"a", "function":"SUM", "limit":123} Received: {"john":140,"Mary":120} Sent: {"item":"a", "function":"MAX", "limit":123} Received: {"john":18,"Mary":12} Sent: {"item":"b", "function":"MIN", "limit":123} Received: {"john":4,"Mary":6} Sent: {"item":"a", "function":"SUM", "limit":321} Received: {"john":240,"Mary":320} Turns out the server's magic formula is $sql="SELECT name, $function($item) AS value FROM my_table WHERE $limit<123 GROUP BY name"; (PS, I won't really do this quite so dangerously). A single database query could return the first three pieces of data, and it seems a shame to do it with three separate queries. Instead, the server could quickly look at the item and the limit, and dynamically create a query which would provide multiple pieces. But if all data is requested at once, my conundrum is how the server should label the pieces of data so when the client gets it back, it knows which one is associated with which sub-request. I was thinking of just an array, or maybe hashing the request and using that as the property. Hope this makes at least some sense as I am just starting off learning about REST.
  20. Thanks Jacques1, I will spend a little time looking into each of your responses. By the way, array_merge() won't work.
  21. Yes, I definitely want SSL, and will get rid of CURLOPT_SSL_VERIFYPEER. Did the other settings look reasonable? Particularly related to SSL and how data was send for PUT and DELETE? Yea, I originally was using array_merge(), but was troubleshooting and forgot to put it back. I'm also thinking passing a "debug" flag to CallAPI, and only returning all the extra info if it is set
  22. Haven't done much with cURL, and nothing using PUT or DELETE methods. Would appreciate any comments on the following script. It is based on cutting and pasting from several sources, and some review of the manual. Particularly, let me know if I am sending data for PUT and DELETE methods correctly. Also, whether my use of CURLOPT_SSL_VERIFYPEER is correct (it doesn't seem to work with SSL without it). Thanks protected function CallAPI($method, $url,array $options, $data = false) { $options = array( CURLOPT_RETURNTRANSFER => true, // return web page CURLOPT_HEADER => false, // don't return headers CURLOPT_FOLLOWLOCATION => true, // follow redirects CURLOPT_ENCODING => "", // handle all encodings CURLOPT_USERAGENT => "unknown",// who am i CURLOPT_AUTOREFERER => true, // set referrer on redirect CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect CURLOPT_TIMEOUT => 120, // timeout on response CURLOPT_MAXREDIRS => 10, // stop after 10 redirects CURLOPT_SSL_VERIFYPEER => false // Disabled SSL Cert checks ); //Optional authentication if (isset($options[CURLOPT_USERPWD])) {$options[CURLOPT_HTTPAUTH]=CURLAUTH_BASIC;} switch (strtolower($method)) { case "get": if ($data) {$url = sprintf("%s?%s", $url, http_build_query($data));} break; case "post": $options[CURLOPT_POST]=1; if ($data) {$options[CURLOPT_POSTFIELDS]=$data;} break; case "put": $options[CURLOPT_PUT]=1; $options[CURLOPT_CUSTOMREQUEST]="PUT"; if ($data) {$options[CURLOPT_POSTFIELDS]=http_build_query($data);} break; case "delete": //$options[CURLOPT_DELETE]=1; $options[CURLOPT_CUSTOMREQUEST]="DELETE"; if ($data) {$options[CURLOPT_POSTFIELDS]=http_build_query($data);} break; default:trigger_error("Invalid HTTP method.", E_USER_ERROR); } $options[CURLOPT_URL]=$url; $ch = curl_init(); curl_setopt_array( $ch, $options ); $content = curl_exec( $ch ); $err = curl_errno( $ch ); $errmsg = curl_error( $ch ); $results = curl_getinfo( $ch ); curl_close( $ch ); $results['errno'] = $err; $results['errmsg'] = $errmsg; $results['content'] = $content; return $results; }
  23. No, not out of the question. It seems excessive as I will only have one row with 4 columns, but maybe I should use one.
  24. I have a small configuration file which PHP must be able to read from and write to. Do you recommend using JSON, or using a PHP ini file along with parse_ini_file()? Please explain your reasoning. If JSON, how do you recommend saving and retrieving the data? For instance, an array or object? If an ini file, how do you recommend saving the file? Thanks
×
×
  • 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.