Complex classes like DAO often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use DAO, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 15 | class DAO { |
||
| 16 | public static $db; |
||
| 17 | private static $objects; |
||
| 18 | |||
| 19 | private static function getObjects(){ |
||
| 20 | if(is_null(self::$objects)){ |
||
| 21 | self::$objects=array(); |
||
| 22 | Logger::log("getObjects","Instanciation de Objects"); |
||
| 23 | } |
||
| 24 | return self::$objects; |
||
| 25 | } |
||
| 26 | |||
| 27 | private static function getInstanceIdInObjects($instance){ |
||
| 28 | $condition=self::getCondition(OrmUtils::getKeyFieldsAndValues($instance)); |
||
| 29 | $condition=preg_replace('/\s|\'+/', '', $condition); |
||
| 30 | return get_class($instance)."#".$condition; |
||
| 31 | } |
||
| 32 | |||
| 33 | private static function getCondition($keyValues){ |
||
| 34 | $retArray=array(); |
||
| 35 | if(is_array($keyValues)){ |
||
| 36 | foreach ($keyValues as $key=>$value){ |
||
| 37 | $retArray[]="`".$key."` = '".$value."'"; |
||
| 38 | } |
||
| 39 | $condition=implode(" AND ", $retArray); |
||
| 40 | }else |
||
| 41 | $condition=$keyValues; |
||
| 42 | return $condition; |
||
| 43 | } |
||
| 44 | |||
| 45 | private static function addInstanceInObjects($instance){ |
||
| 46 | self::getObjects(); |
||
| 47 | self::$objects[self::getInstanceIdInObjects($instance)]=$instance; |
||
| 48 | } |
||
| 49 | |||
| 50 | private static function getInstanceInObjects($className,$keyValue){ |
||
| 61 | |||
| 62 | /** |
||
| 63 | * Charge les membres associés à $instance par une relation de type ManyToOne |
||
| 64 | * @param object $instance |
||
| 65 | * @param mixed $value |
||
| 66 | * @param array $annotationArray |
||
| 67 | */ |
||
| 68 | private static function getOneManyToOne($instance,$value,$annotationArray){ |
||
| 69 | $class=get_class($instance); |
||
| 70 | $member=$annotationArray["member"]; |
||
| 71 | $key=OrmUtils::getFirstKey($annotationArray["className"]); |
||
| 72 | $kv=array($key=>$value); |
||
| 73 | $obj=self::getOne($annotationArray["className"], $kv,false); |
||
| 74 | if($obj!==null){ |
||
| 75 | Logger::log("getOneManyToOne", "Chargement de ".$member." pour l'objet ".$class); |
||
| 76 | $accesseur="set".ucfirst($member); |
||
| 77 | if(method_exists($instance,$accesseur)){ |
||
| 78 | $instance->$accesseur($obj); |
||
| 79 | return; |
||
| 80 | } |
||
| 81 | } |
||
| 82 | } |
||
| 83 | |||
| 84 | /** |
||
| 85 | * Affecte/charge les enregistrements fils dans le membre $member de $instance. |
||
| 86 | * Si $array est null, les fils sont chargés depuis la base de données |
||
| 87 | * @param object $instance |
||
| 88 | * @param string $member Membre sur lequel doit être présent une annotation OneToMany |
||
| 89 | * @param array $array paramètre facultatif contenant la liste des fils possibles |
||
| 90 | * @param array $annot used internally |
||
| 91 | */ |
||
| 92 | public static function getOneToMany($instance,$member,$array=null,$annot=null){ |
||
| 93 | $ret=array(); |
||
| 94 | $class=get_class($instance); |
||
| 95 | if(!isset($annot)) |
||
| 96 | $annot=OrmUtils::getAnnotationInfoMember($class,"#oneToMany", $member); |
||
| 97 | if($annot!==false){ |
||
| 98 | $fkAnnot=OrmUtils::getAnnotationInfoMember($annot["className"], "#joinColumn",$annot["mappedBy"]); |
||
| 99 | if($fkAnnot!==false){ |
||
| 100 | $fkv=OrmUtils::getFirstKeyValue($instance); |
||
| 101 | if(is_null($array)){ |
||
| 102 | $ret=self::getAll($annot["className"],$fkAnnot["name"]."='".$fkv."'"); |
||
| 103 | }else{ |
||
| 104 | self::getOneToManyFromArray($ret, $array, $fkv, $annot); |
||
| 105 | } |
||
| 106 | self::setToMember($member, $instance, $ret, $class, "getOneToMany"); |
||
| 107 | } |
||
| 108 | } |
||
| 109 | return $ret; |
||
| 110 | } |
||
| 111 | |||
| 112 | private static function getOneToManyFromArray(&$ret,$array,$fkv,$annot){ |
||
| 113 | $elementAccessor="get".ucfirst($annot["mappedBy"]); |
||
| 114 | foreach ($array as $element){ |
||
| 115 | $elementRef=$element->$elementAccessor(); |
||
| 116 | if(!is_null($elementRef)){ |
||
| 117 | $idElementRef=OrmUtils::getFirstKeyValue($elementRef); |
||
| 118 | if($idElementRef==$fkv) |
||
| 119 | $ret[]=$element; |
||
| 120 | } |
||
| 121 | } |
||
| 122 | } |
||
| 123 | |||
| 124 | private static function setToMember($member,$instance,$value,$class,$part){ |
||
| 133 | /** |
||
| 134 | * @param object $instance |
||
| 135 | * @param ManyToManyParser $parser |
||
| 136 | * @return PDOStatement |
||
| 137 | */ |
||
| 138 | private static function getSQLForJoinTable($instance,ManyToManyParser $parser){ |
||
| 144 | /** |
||
| 145 | * Affecte/charge les enregistrements fils dans le membre $member de $instance. |
||
| 146 | * Si $array est null, les fils sont chargés depuis la base de données |
||
| 147 | * @param object $instance |
||
| 148 | * @param string $member Membre sur lequel doit être présent une annotation ManyToMany |
||
| 149 | * @param array $array paramètre facultatif contenant la liste des fils possibles |
||
| 150 | */ |
||
| 151 | public static function getManyToMany($instance,$member,$array=null){ |
||
| 171 | |||
| 172 | private static function getManyToManyFromArray(&$ret,$instance,$array,$class,$parser){ |
||
| 196 | /** |
||
| 197 | * Retourne un tableau d'objets de $className depuis la base de données |
||
| 198 | * @param string $className nom de la classe du model à charger |
||
| 199 | * @param string $condition Partie suivant le WHERE d'une instruction SQL |
||
| 200 | * @return array |
||
| 201 | */ |
||
| 202 | public static function getAll($className,$condition='',$loadManyToOne=true,$loadOneToMany=false){ |
||
| 222 | |||
| 223 | private static function loadObjectFromRow($row,$className,$invertedJoinColumns,$oneToManyFields){ |
||
| 241 | /** |
||
| 242 | * Retourne le nombre d'objets de $className depuis la base de données respectant la condition éventuellement passée en paramètre |
||
| 243 | * @param string $className nom de la classe du model à charger |
||
| 244 | * @param string $condition Partie suivant le WHERE d'une instruction SQL |
||
| 245 | */ |
||
| 246 | public static function count($className,$condition=''){ |
||
| 252 | |||
| 253 | /** |
||
| 254 | * Retourne une instance de $className depuis la base de données, à partir des valeurs $keyValues de la clé primaire |
||
| 255 | * @param String $className nom de la classe du model à charger |
||
| 256 | * @param Array|string $keyValues valeurs des clés primaires ou condition |
||
| 257 | */ |
||
| 258 | public static function getOne($className,$keyValues,$loadManyToOne=true,$loadOneToMany=false){ |
||
| 277 | |||
| 278 | /** |
||
| 279 | * Supprime $instance dans la base de données |
||
| 280 | * @param Classe $instance instance à supprimer |
||
| 281 | */ |
||
| 282 | public static function remove($instance){ |
||
| 293 | |||
| 294 | /** |
||
| 295 | * Insère $instance dans la base de données |
||
| 296 | * @param object $instance instance à insérer |
||
| 297 | * @param $insertMany si vrai, sauvegarde des instances reliées à $instance par un ManyToMany |
||
| 298 | */ |
||
| 299 | public static function insert($instance,$insertMany=false){ |
||
| 320 | |||
| 321 | /** |
||
| 322 | * Met à jour les membres de $instance annotés par un ManyToMany |
||
| 323 | * @param object $instance |
||
| 324 | */ |
||
| 325 | public static function insertOrUpdateAllManyToMany($instance){ |
||
| 334 | |||
| 335 | /** |
||
| 336 | * Met à jour le membre $member de $instance annoté par un ManyToMany |
||
| 337 | * @param Object $instance |
||
| 338 | * @param String $member |
||
| 339 | */ |
||
| 340 | public static function insertOrUpdateManyToMany($instance,$member){ |
||
| 371 | /** |
||
| 372 | * Met à jour $instance dans la base de données. |
||
| 373 | * Attention de ne pas modifier la clé primaire |
||
| 374 | * @param Classe $instance instance à modifier |
||
| 375 | * @param $updateMany Ajoute ou met à jour les membres ManyToMany |
||
| 376 | */ |
||
| 377 | public static function update($instance,$updateMany=false){ |
||
| 394 | |||
| 395 | /** |
||
| 396 | * Réalise la connexion à la base de données en utilisant les paramètres passés |
||
| 397 | * @param string $dbName |
||
| 398 | * @param string $serverName |
||
| 399 | * @param string $port |
||
| 400 | * @param string $user |
||
| 401 | * @param string $password |
||
| 402 | */ |
||
| 403 | public static function connect($dbName,$serverName="127.0.0.1",$port="3306",$user="root",$password=""){ |
||
| 407 | } |
||
| 408 |
If you define a variable conditionally, it can happen that it is not defined for all execution paths.
Let’s take a look at an example:
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.
Available Fixes
Check for existence of the variable explicitly:
Define a default value for the variable:
Add a value for the missing path: