Overview

Namespaces

  • None
  • PHP

Classes

  • HRC

Exceptions

  • HRCException
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * Description of HRC (HTTPRequestChecker)
  5:  *
  6:  * Class designed to check input parameters(HTTP request) using
  7:  *  various validation rules.
  8:  *
  9:  * @author Radim SVOBODA <r.svoboda@pixvalley.com>
 10:  * @date 2012/12/14
 11:  */
 12: class HRC
 13: {
 14:     const   BOOL=1,
 15:             EMAIL=2,
 16:             FLOAT=3,
 17:             INT=4,
 18:             IP=5,
 19:             REGEXP=6,
 20:             URL=7
 21:             //LENGTH=8,
 22:             //COUNT=9
 23:             ;
 24: 
 25:     protected $globalToCheck;// = "REQUEST";
 26:     protected $inputParams,
 27:               $currentInput
 28:               ;
 29: 
 30:    //protected $inputDefaults = array();
 31: 
 32:     public function __construct()
 33:     {
 34:         $this->reset();
 35: 
 36:         $this->setRequestMethod();
 37:     }
 38:     public function reset()
 39:     {
 40:         $this->inputParams = array();
 41:         $this->currentInput = null;
 42: 
 43:         
 44:         //$this->inputDefaults = array();
 45: 
 46:         return $this;
 47:     }
 48:     /**
 49:      * Clones the current object, runs the reset() method and returns the object
 50:      *
 51:      * @return \HRC the newly created/cloned object
 52:      */
 53:     public function newInstance()
 54:     {
 55:         //$o = new $this;
 56:         $o = clone $this;
 57:         return $o->reset();
 58:     }
 59:     /**
 60:      * Compares two operands with a specified operator
 61:      *
 62:      * @static
 63:      * @param type $x operand
 64:      * @param type $y operand
 65:      * @param type $operator string representation of comparison operator.
 66:      * Supported are: "==", "===", "!=", "!==", ">", ">=", "<", "<="
 67:      * @return boolean the comparison result; If operator is not supported, NULL
 68:      */
 69:     public static function cmp($x,$y,$operator="==")
 70:     {
 71:         switch($operator):
 72:             case "==":  return ($x==$y);
 73:             case "===": return ($x===$y);
 74:             case "!=":  return ($x!=$y);
 75:             case "!==": return ($x!==$y);
 76:             case ">":   return ($x>$y);
 77:             case ">=":  return ($x>=$y);
 78:             case "<":   return ($x<$y);
 79:             case "<=":  return ($x<=$y);
 80:         endswitch;
 81:         //operator not found
 82:         return null;
 83:     }
 84:     /**
 85:      * Based on the first parameter which is a rule/callback (int/callable)
 86:      * the method createHRCRule or createCustomRule is called. Check those
 87:      * methods for more information on which parameters to pass.
 88:      *
 89:      * @static
 90:      * @param callable|int $mRule
 91:      * @return array created rule
 92:      */
 93:     public static function createRule($mRule)
 94:     {
 95:         $aArgs = func_get_args();
 96:         $staticMethod =  is_int($mRule) ? "createHRCRule" : "createCustomRule";
 97: 
 98:         return call_user_func_array(array(__CLASS__, $staticMethod), $aArgs);
 99:     }
100: 
101:     /**
102:      *
103:      * @param callable $cRule
104:      * @param array $aArgs
105:      * @param int $iArgIndex optional
106:      * @param string $sCompareOperator
107:      * @param mixed $mCompareValeu
108:      * @return array
109:      */
110:     public static function createCustomRule($cRule, 
111:                             $aArgs=array(), $iArgIndex=null,
112:                             $sCompareOperator="==", $mCompareValeu=true)
113:     {
114:         $a =  array(
115:             "fn"=>$cRule, "args"=>$aArgs, "argIndex"=>$iArgIndex,
116:            // "equalsVal"=>$bEqualsTo, "strictEqual"=>$bStrictEqual
117:             "cmpOp"=>$sCompareOperator, "cmpVal"=>$mCompareValeu
118:             );
119:         if( is_string( $iArgIndex) )
120:         {//$iArgIndex is missing; should be set to NULL(==appending)
121:             $a["cmpVal"] = $a["cmpOp"];
122:             $a["cmpOp"] = $a["argIndex"];
123:             $a["argIndex"] = null;
124:         }
125: 
126:         return $a;
127:     }
128:     
129:     /**
130:      * Creates a rule based on the arguments. Mostly uses the function
131:      * filter_var. Using this method it is easier to pass arguments than it
132:      * would be in createCustomRule using "filter_var" as callable.
133:      * Mostly, all the arguments, except the first one, are optional
134:      *
135:      * <code>
136:      * <pre>
137:      * //chcecking for boolean using filter_var validation filter
138:      * ->createHRCRule(HRC::BOOL, array|int $flag)
139:      *
140:      *  //chcecking for integer using filter_var validation filter
141:      *  //if you e.g. want to set only max. value, set min. val. to NULL
142:      * ->createHRCRule(HRC::INT, int $iMin=null, int $iMax=null, array|int $flag)
143:      *
144:      *  //chcecking for float using filter_var validation filter
145:      * ->createHRCRule(HRC::FLOAT, string $sDecimal=null, array|int $flag)
146:      *
147:      *  //chcecking for IP using filter_var validation filter
148:      * ->createHRCRule(HRC::IP, array|int $flag)
149:      *
150:      *  //chcecking for URL using filter_var validation filter
151:      * ->createHRCRule(HRC::URL, array|int $flag)
152:      *
153:      *  //chcecking for e-mail using filter_var validation filter
154:      * ->createHRCRule(HRC::EMAIL)
155:      *
156:      *  //chcecking if the input parameter matches regular expression
157:      *  //Of course, the $sRegExp is mandatory
158:      * ->createHRCRule(HRC::REGEXP, $sRegExp)
159:      * </pre>
160:      * </code>
161:      *
162:      * @static
163:      * @param int $iRule class constant indicating which rule to use
164:      * @param mixed $arg1
165:      * @param mixed $arg2
166:      * @param mixed $arg3
167:      * @return array|null
168:      */
169:     public static function createHRCRule($iRule,
170:             $arg1=null, $arg2=null, $arg3=null )
171:     {
172:         //mostly filter_var function is used which needs specific options
173:         $aOptions = array();
174:         //value indicating failure
175:         $mFailureValue=false;
176:         //compares filter_var result with the failure value
177:         $sCmpOperator = "!==";
178:         //indicating the retrieved param should be the first argument passed
179:         //to filter_var
180:         $iParamIndex = 0;
181: 
182:         switch($iRule):
183:             
184:             /*case self::LENGTH:
185:             case self::COUNT:
186:             
187:                 throw new Exception("not implemented");*/
188: 
189:             case self::BOOL:                
190:                  if($arg1!==null)//flags
191:                  {
192:                      $aOptions["flags"]= is_array($arg1) ? $arg1 : array($arg1);
193: 
194:                      if( in_array( FILTER_NULL_ON_FAILURE, $aOptions["flags"], true ))
195:                              $mFailureValue=null;
196:                  }
197:                  return self::createCustomRule(
198:                          "filter_var",
199:                          array(FILTER_VALIDATE_BOOLEAN, $aOptions),$iParamIndex,
200:                          $sCmpOperator, $mFailureValue
201:                          );
202:             case self::INT:
203:                  if($arg1!==null)
204:                  {
205:                      $aOptions["min_range"]=$arg1;
206:                  }
207:                  if($arg2!==null)
208:                  {
209:                      $aOptions["max_range"]=$arg2;
210:                  }
211:                  if( count( $aOptions) > 0 )
212:                  {//if there are any values, put them at the "right place"
213:                      $aOptions = array("options"=>$aOptions);
214:                  }
215:                  if($arg3!==null)//flags
216:                  {
217:                      $aOptions["flags"]= is_array($arg3) ? $arg3 : array($arg3);
218:                  }
219:                  return self::createCustomRule(
220:                          "filter_var",
221:                          array(FILTER_VALIDATE_INT, $aOptions), $iParamIndex,
222:                          $sCmpOperator, $mFailureValue
223:                          );
224:             case self::FLOAT:
225:                  if($arg1!==null)//decimal (string character)
226:                  {
227:                      $decimal = array("decimal"=>$arg1);
228:                      $aOptions["options"]=$decimal;
229:                  }
230:                  if($arg2!==null)//flags
231:                  {
232:                      $aOptions["flags"]= is_array($arg2) ? $arg2 : array($arg2);
233:                  }
234:                  return self::createCustomRule(
235:                          "filter_var",
236:                          array(FILTER_VALIDATE_FLOAT, $aOptions), $iParamIndex,
237:                          $sCmpOperator, $mFailureValue
238:                          );
239: 
240:             case self::IP:
241:                  if($arg1!==null)//flags
242:                  {
243:                      $aOptions["flags"]= is_array($arg1) ? $arg1 : array($arg1);
244:                  }
245:                  return self::createCustomRule(
246:                          "filter_var",
247:                          array(FILTER_VALIDATE_IP, $aOptions), $iParamIndex,
248:                          $sCmpOperator, $mFailureValue
249:                          );
250:             case self::URL:
251:                  if($arg1!==null)//flags
252:                  {
253:                      $aOptions["flags"]= is_array($arg1) ? $arg1 : array($arg1);
254:                  }
255:                  return self::createCustomRule(
256:                          "filter_var",
257:                          array(FILTER_VALIDATE_URL, $aOptions), $iParamIndex,
258:                          $sCmpOperator, $mFailureValue
259:                          );
260:             case self::EMAIL:
261:                 return
262:                     self::createCustomRule( "filter_var",
263:                          FILTER_VALIDATE_EMAIL, $iParamIndex,
264:                          $sCmpOperator, $mFailureValue
265:                          );
266:             case self::REGEXP:
267:             //without regexp passed, it doesnt have sense...
268:             //so there is no checking for it
269:                 $aOptions = array("options"=>array("regexp"=>$arg1));
270:                 return self::createCustomRule( "filter_var",
271:                          array(FILTER_VALIDATE_REGEXP, $aOptions), $iParamIndex,
272:                          $sCmpOperator, $mFailureValue
273:                          );
274: 
275:         endswitch;
276:         
277:         return null;
278:     }
279:     /*public function isValid()
280:     {
281:         return true;
282:     }*/
283: 
284:     /**
285:      *
286:      * @param string $sType of request, e.g. REQUEST, POST, GET
287:      * @return \HRC the object instance to support chanability
288:      */
289:     public function setRequestMethod($sType="REQUEST")
290:     {
291:         $sType = strtoupper($sType);
292:         if( $sType=="REQUEST")
293:             $this->globalToCheck =&$_REQUEST;
294:         else
295:             $this->globalToCheck =&$GLOBALS["_$sType"];
296: 
297:         return $this;
298:     }
299: 
300:     /**
301:      * Stores the information about a desired value in superglobals to check
302:      *
303:      * @param string|array $key key of value we want to check. When array is
304:      * e.g. array("cat","col") it would check for instance $_POST["cat"]["col"]
305:      * @param string $desiredName name you want to use within HRC. It is
306:      * mandatory when $key is an array
307:      * @return \HRC instance
308:      */
309:     public function check($key, $sDesiredName=null)
310:     {
311:         $name = empty($sDesiredName) ?  $key : $sDesiredName ;
312:         $this->inputParams[$name] =  array("key"=>$key);        
313:         $this->currentInput = $name;
314: 
315:         return $this;
316:     }
317: 
318:     public function useSettingFor($key, $sDesiredName=null)
319:     {
320:         $name = empty($sDesiredName) ?  $key : $sDesiredName ;
321:         $aSetting = $this->_get();//obtained by reference...
322:         $this->inputParams[$name] =  $aSetting;
323:         $this->inputParams[$name]["key"] = $key;
324:         $this->currentInput = $name;
325: 
326:         return $this;
327:     }
328:     /**
329:      *
330:      * @param callable $callable callback to execute
331:      * @param type $value value we want to pass to the callback. Thi value is
332:      * usually the one from superglobals
333:      * @param array $aArgs list of additional arguments passed to the callback.
334:      * If $aArgs is not an array, it is automatically wrapped into one.
335:      * @param int $iValIndex zero-based position index of $value in the $aArgs.
336:      * If null, $value is appended to $aArgs
337:      * @return mixed callback return value
338:      * @throws Exception in case an exception from callback is thrown, it is
339:      * re-thrown
340:      */
341:     protected function _callFn($callable, $value, $aArgs=array(), $iValIndex=null)
342:     {
343:         if( !is_array($aArgs) )
344:             $aArgs=array($aArgs);
345: 
346:         if($iValIndex===null)
347:         {//append
348:             $aArgs[]=$value;
349:         }else{ //put the obtained value at the right position
350:             $aArgs = array_merge(
351:                     array_slice($aArgs, 0, $iValIndex),
352:                     array($value),
353:                     array_slice($aArgs, $iValIndex) );
354:         }
355:         
356:         try
357:         {
358:             return call_user_func_array($callable, $aArgs);
359:         }catch(Exception $ex){
360:             throw $ex; //just re-throw
361:         }
362:     }
363:     /**
364:      * Gets a value from a superglobal
365:      *
366:      * @param string|array $key key of variable|array of keys for e.g.
367:      * $_POST['category']['name']
368:      * @param string|array $default value to return if the searched var
369:      * is not found
370:      * @return string|array retrieved varible; by reference
371:      * @throws HRCException if the var doesn't exist, and no default value is set
372:      */
373:     protected function &_getFromGlobal($key, $default=null)
374:     {
375:         if( !is_array($key) )
376:             $key=array($key);
377:         $keyString = join("][",$key);
378:         //create var to access the global scope easily
379:         $glob =& $this->globalToCheck;
380:         while( ( $k = array_shift($key)) )
381:         {
382:             if( isset($glob[$k]) )
383:             {
384:                 $glob=&$glob[$k];
385:             }
386:             else if( $default!==null )
387:             {
388:                 return $default;
389:             }
390:             else
391:             {
392:                throw new HRCException(
393:                        "[$keyString] not found",
394:                        HRCException::NOT_FOUND,
395:                        $key
396:                        );
397:             }
398:         }
399:         return $glob;
400:     }
401:     /**
402:      * Gets the parameter setting
403:      * 
404:      * @param string $sName name of the parameter
405:      * @return array setting for a parameter. The current parameter is returned
406:      * if no parameter spiceifed. NULL if not found.
407:      */
408:     protected function &_get($sName=null)
409:     {
410:         $name = ($sName===null) ? $this->currentInput : $sName;
411: 
412:         /*if(empty($this->inputParams[$name]))
413:             return null;
414: 
415:         return $this->inputParams[$name];*/
416:         $null = null;
417:         $a = array();
418:         if( empty($this->inputParams[$name]) )
419:         {
420:            return  $null;
421:         }
422:         else
423:         {
424:             return $this->inputParams[$name];
425:         }
426:             
427:     }
428:     public function setCurrent($sName)
429:     {
430:         $this->currentInput = $sName;
431:         return $this;
432:     }
433:     public function get($name)
434:     {
435:         //get the settings
436:         $param;
437:         if( isset($this->inputParams[$name]) )
438:             $param =& $this->inputParams[$name];
439:         else
440:             throw new HRCException(
441:                     "'$name' not defined",
442:                     HRCException::NOT_DEFINED
443:                     );
444:         $value;
445:         try
446:         {
447:             $mDefault = isset($param['default']) ? $param['default'] : null;
448:             $value =  $this->_getFromGlobal($param["key"], $mDefault);
449:             /*if(isset($param['default']))//default value set?
450:             {
451:                 $value =  $this->_getFromGlobal($param["key"], $param['default']);
452:             }
453:             else
454:             {
455:                 $value =  $this->_getFromGlobal($param["key"]);
456:             }*/
457:             //Validation rules
458:             if(isset($param['rules']))
459:             {
460:                 foreach($param['rules'] as $aRule)
461:                 {
462:                     if( ! $this->_validate( $value, $aRule ))
463:                     {
464:                         throw new HRCException(
465:                                 "'$name' has invalid format",
466:                                 HRCException::NOT_VALID,
467:                                 array("VALUE"=>$value, "RULE"=>$aRule));
468:                     }
469:                 }
470:             }
471:         }
472:         catch(Exception $ex)
473:         {
474:             throw $ex;
475:         }
476: 
477:         return $value;
478: 
479:     }
480:     //TODO: test it!
481:     public function getAll($returnArrayObject=false)
482:     {
483:         $aResult=array();
484:         $aNames = array_keys($this->inputParams);
485:         foreach($aNames as $key)
486:         {
487:             try
488:             {
489:             $aResult[$key] = $this->get($key);
490:             }
491:             catch(Exception $ex)
492:             {
493:                 throw $ex;
494:             }
495: 
496:         }
497: 
498:         //add conversion to object if needed
499:         if( $returnArrayObject )
500:             $aResult = new ArrayObject ( $aResult, ArrayObject::ARRAY_AS_PROPS);
501:         
502:         return $aResult;
503: 
504:     }
505:     /**
506:      * In case a variable is not set (!isset()) but we don't want any error to
507:      * occur. We can set a default value which is used in case the desired
508:      * parameter is not set.
509:      *
510:      * @param string|array $value the default value for a parameter if it is not
511:      * set. Note that it has to be a string or possibly an array.
512:      * More specifically, the value NULL will not work.
513:      * @param string $sName name of the parameter in \HRC. If it is not set, the
514:      * last one/current one is used
515:      * @return \HRC instance
516:      * @throws HRCException
517:      */
518:     public function setDefault($value, $sName=null)
519:     {
520:         $name = ($sName===null) ? $this->currentInput : $sName;
521:         if( empty($this->inputParams[$name]) )
522:         {
523:             throw new HRCException(
524:                     "Param '$name' not set", 
525:                     HRCException::NOT_DEFINED,
526:                     array($value, $sName)
527:                     );
528:         }
529:         
530:         $this->inputParams[$name]['default'] = $value;
531: 
532:         return $this;
533:     }
534:     /**
535:      * The method adds a new rule to used to validate input parameter.
536:      * Based on the arguments, to create a new rule, a static method
537:      * "createCustomRule" or "createHRCRule" is used to generate the actual rule.
538:      * Then, it is saved inside our object. For more information see those
539:      * methods
540:      *
541:      * @see HRC::createHRCRule()
542:      * @TODO comment HRC::createCustomRule
543:      *
544:      * @param mixed $mRule
545:      * @param type $aArgs
546:      * @param type $iArgIndex
547:      * @param type $sCompareOperator
548:      * @param type $mCompareValue
549:      * @return \HRC instance
550:      */
551:     public function addRule($mRule, $aArgs=array(), $iArgIndex=null,
552:                             $sCompareOperator="==", $mCompareValue=true//,$sName=null
553:                            )
554:     {
555:         //$name = ($sName===null) ? $this->currentInput : $sName;
556:         //$param =& $this->_get( );//
557:         //create an array of rules if not any
558:         //if( !isset($param["rules"]) )
559:          //   $param["rules"]=array();
560:         //create the rule
561: 
562:         $aRule;
563:         if( is_int($mRule) )
564:         {//use only arguments that are passed by user/programmer...
565:             $aRule = call_user_func_array( array(__CLASS__, "createHRCRule"),
566:                                            func_get_args()
567:                                          );
568:         }
569:         else
570:         { //use all the parametrs including the default values...
571:             $aRule = self::createCustomRule(
572:                 $mRule, $aArgs, $iArgIndex, $sCompareOperator, $mCompareValue);
573:         }
574:         //store the rule
575:         return $this->addMultiRule($aRule, false);
576:         //$param["rules"][] = array( $aRule );
577:         
578:        // return $this;
579: 
580:     }
581: //TODO fix the params
582:     public function addArrayItemRule($cRule, $aArgs=array(), $iArgIndex=null,
583:                             $sCompareOperator="==", $mCompareValue=true//,$sName=null
584:                            )
585:     {
586:         $aRule;        
587:         if( is_int($cRule) )
588:         {//use only arguments that are passed by user/programmer...
589:             $aRule = call_user_func_array( array(__CLASS__, "createHRCRule"),
590:                                            func_get_args()
591:                                          );
592:         }
593:         else
594:         { //use all the parametrs including the default values...
595:             $aRule = self::createCustomRule(
596:                 $cRule, $aArgs, $iArgIndex, $sCompareOperator, $mCompareValue);
597:         }
598:         
599:         
600:         //store the rule
601:         return $this->addMultiRule($aRule, true);
602:         //return $this;
603:     }
604:     public function addMultiRule( array $aRule1, $aRuleN=null,
605:                                 $bCheckArrayItems=false)//, $sName=null
606:     {
607:         $aRules =  func_get_args();//array of arrays
608:  
609:         if(  !is_array( $aRules[count($aRules)-1] ) )//last arg is not aRule
610:         {   //indicates if we should check all array items
611:              $bArrayItems =array_pop($aRules);
612:              if( $bArrayItems )
613:              {
614:                  foreach( $aRules as &$aRule)
615:                  {//set the attribute indicating we should check every item in
616:                   //an array
617:                      $aRule["checkArrayItems"] = true;
618:                  }
619:              }
620:         }
621:         //get the current param setting
622:         $param =& $this->_get();
623:         if($param===null)
624:             return null;
625:         //create an array of rules if not any
626:         if( !isset($param["rules"]) )
627:             $param["rules"]=array();
628: 
629:         $param["rules"][] = $aRules;
630: //var_dump( array("PARAM"=>$param, "NAME"=>$this->inputParams[$name],"--------------------------------------------------------------------------" ));
631:         return $this;
632: 
633:     }
634:     protected function _validateString($string, $aRule)
635:     {
636:         $returnVal = $this->_callFn(
637:                             $aRule["fn"], $string,
638:                             $aRule["args"], $aRule["argIndex"]
639:                             );
640:         //Is the $returnVal ok?
641:         return self::cmp( $returnVal, $aRule["cmpVal"], $aRule["cmpOp"] ) ;
642: 
643:     }
644:     protected function _validateArray($array, $aRule)
645:     {
646:         if(  is_array($array) )
647:         {
648:             foreach($array as $item)
649:             {   //each element needs to pass the rules
650:                 if( ! $this->_validateString($item, $aRule))
651:                 {
652: //echo "||IVALID $item::";
653:                     return false;
654:                 }
655:             }
656:             return true;
657:         }
658:         else
659:         {   //$array is not array
660: //echo"NOT ARRAY";
661:             return false;
662:         }
663:         
664: 
665:     }
666:     protected function _validate($value, $aRule)
667:     {
668:        
669: 
670:         try
671:         {
672:             foreach($aRule as $aOneRule)
673:             {
674:                 //should we check each array item?
675:                 if( ! empty($aOneRule["checkArrayItems"]) )
676:                 {
677: //var_dump( $value, $aOneRule );
678:                     if(  $this->_validateArray($value, $aOneRule))
679:                         return true;//at least one rule qualifies
680:                 }
681:                 else
682:                 {
683:                     if(  $this->_validateString($value, $aOneRule))
684:                         return true;//at least one rule qualifies
685:                 }
686:                 
687:             }
688: 
689: 
690:             //----------------------------
691:            /* if( $isArray )
692:             {
693:                 if( ! is_array($value) )
694:                     return false;
695: 
696:                 foreach($value as $arrayItem)
697:                 {//one invalid item means it's all wrong...
698:                     //recursive call
699:                     if ($this->_validate($arrayItem, $aRule, false)===false)
700:                     {                            
701:                             //throw new Exception(print_r(array($arrayItem, $aRules, false)));
702:                             return false;
703:                     }
704:                 }
705:                 return true;//the whole array is ok
706: 
707:             }
708:             else
709:                 foreach($aRule as $aOneRule)
710:                 {
711:                     $returnVal = $this->_callFn(
712:                             $aOneRule["fn"], $value,
713:                             $aOneRule["args"], $aOneRule["argIndex"]
714:                             );
715:                     //$aRule["cmpVal"]$aRule["cmpOp"]
716:                     if( self::cmp( $returnVal, $aOneRule["cmpVal"], $aOneRule["cmpOp"] ) )
717:                             return true;
718:                     
719:                     if(empty($aRule["strictEqual"]))
720:                     {
721:                         if($returnVal == $aRule["equalsVal"])
722:                             return true;//at least one rule qualifies
723:                     }
724:                     else
725:                     {
726:                         if($returnVal === $aRule["equalsVal"])
727:                             return true;//at least one rule qualifies
728:                     }
729: 
730:                 }*/
731:         }catch(Exception $ex){
732:             throw $ex;
733:         }
734:         return false;
735:     }
736:     
737:    /* protected function _validateString()
738:     {
739: 
740:     }//*/
741: 
742: }
743: 
744: 
745: 
746: 
747: class HRCException extends Exception
748: {
749:     const NOT_FOUND=100,//for wrongly specified superglobal
750:           NOT_DEFINED=110,
751:           NOT_VALID=200,
752:           NOT_ARRAY=210,//supplied argument is not an array, ut should be
753:           CALLBACK=300
754:           ;
755:     /* Array containing data that could be useful for debuging  */
756:     protected $aDev;// = array();
757:     // Redefine the exception so message isn't optional
758:     public function __construct($message, $code = 0, $aDev=array()) {
759:         // some code
760:         $this->aDev = $aDev;
761:         // make sure everything is assigned properly
762:         parent::__construct($message, $code);
763:     }
764: 
765:     // custom string representation of object
766:     public function __toString() {
767:         return __CLASS__ . ": [{$this->code}] {$this->message}\n";
768:     }
769: 
770:     public function getDevInfo() {
771:         return $this->aDev;
772:     }
773: }
774: 
775: 
776: 
API documentation generated by ApiGen 2.8.0