可以通过这个一刀切的功能运行所有Mysqli查询(SELECT,UPDATE,DELETE等)吗?

Pro*_*irl 0 php database mysqli prepared-statement

我是Mysqli的新手(从MySQL切换),所以为了保持简单,安全和安全,通过这个一刀切的功能运行绝对所有Mysqli查询是否有意义?

为什么或为什么不以及什么是利弊?

function mysqli_prepared_query($link,$sql,$typeDef = FALSE,$params = FALSE){ 
  if($stmt = mysqli_prepare($link,$sql)){ 
    if(count($params) == count($params,1)){ 
      $params = array($params); 
      $multiQuery = FALSE; 
    } else { 
      $multiQuery = TRUE; 
    }  

    if($typeDef){ 
      $bindParams = array();    
      $bindParamsReferences = array(); 
      $bindParams = array_pad($bindParams,(count($params,1)-count($params))/count($params),"");         
      foreach($bindParams as $key => $value){ 
        $bindParamsReferences[$key] = &$bindParams[$key];  
      } 
      array_unshift($bindParamsReferences,$typeDef); 
      $bindParamsMethod = new ReflectionMethod('mysqli_stmt', 'bind_param'); 
      $bindParamsMethod->invokeArgs($stmt,$bindParamsReferences); 
    } 

    $result = array(); 
    foreach($params as $queryKey => $query){ 
      foreach($bindParams as $paramKey => $value){ 
        $bindParams[$paramKey] = $query[$paramKey]; 
      } 
      $queryResult = array(); 
      if(mysqli_stmt_execute($stmt)){ 
        $resultMetaData = mysqli_stmt_result_metadata($stmt); 
        if($resultMetaData){                                                                               
          $stmtRow = array();   
          $rowReferences = array(); 
          while ($field = mysqli_fetch_field($resultMetaData)) { 
            $rowReferences[] = &$stmtRow[$field->name]; 
          }                                
          mysqli_free_result($resultMetaData); 
          $bindResultMethod = new ReflectionMethod('mysqli_stmt', 'bind_result'); 
          $bindResultMethod->invokeArgs($stmt, $rowReferences); 
          while(mysqli_stmt_fetch($stmt)){ 
            $row = array(); 
            foreach($stmtRow as $key => $value){ 
              $row[$key] = $value;           
            } 
            $queryResult[] = $row; 
          } 
          mysqli_stmt_free_result($stmt); 
        } else { 
          $queryResult[] = mysqli_stmt_affected_rows($stmt); 
        } 
      } else { 
        $queryResult[] = FALSE; 
      } 
      $result[$queryKey] = $queryResult; 
    } 
    mysqli_stmt_close($stmt);   
  } else { 
    $result = FALSE; 
  } 

  if($multiQuery){ 
    return $result; 
  } else { 
    return $result[0]; 
  } 
} 
?> 

Example(s): 
For a table of firstName and lastName: 
John Smith 
Mark Smith 
Jack Johnson 
Bob Johnson 

<?php 
//single query, single result 
$query = "SELECT * FROM names WHERE firstName=? AND lastName=?"; 
$params = array("Bob","Johnson"); 

mysqli_prepared_query($link,$query,"ss",$params) 
/* 
returns array( 
0=> array('firstName' => 'Bob', 'lastName' => 'Johnson') 
) 
*/ 

//single query, multiple results 
$query = "SELECT * FROM names WHERE lastName=?"; 
$params = array("Smith"); 

mysqli_prepared_query($link,$query,"s",$params) 
/* 
returns array( 
0=> array('firstName' => 'John', 'lastName' => 'Smith') 
1=> array('firstName' => 'Mark', 'lastName' => 'Smith') 
) 
*/ 

//multiple query, multiple results 
$query = "SELECT * FROM names WHERE lastName=?"; 
$params = array(array("Smith"),array("Johnson")); 

mysqli_prepared_query($link,$query,"s",$params) 
/* 
returns array( 
0=> 
array( 
0=> array('firstName' => 'John', 'lastName' => 'Smith') 
1=> array('firstName' => 'Mark', 'lastName' => 'Smith') 
) 
1=> 
array( 
0=> array('firstName' => 'Jack', 'lastName' => 'Johnson') 
1=> array('firstName' => 'Bob', 'lastName' => 'Johnson') 
) 
) 
*/ 
Run Code Online (Sandbox Code Playgroud)

Gor*_*onM 9

对不起,但不,我认为这是一个糟糕的主意.

一个好的功能/方法应该是简短的,并且设计为做一件事而且只做一件事.它还应尽可能避免使用分支逻辑(将if和switch语句的数量保持在最小值).这些功能很容易理解,因为它们的内部工作可以用相对较少的努力来掌握.

功能越长,理解起来就越困难,因为程序员必须更多地掌握它的工作原理.函数包含的if/switch/try/catch/throw语句越多,理解起来就越难理解,因为它们会修改执行可能流经函数的方式.您必须考虑称为npath复杂性的事物(函数可以执行的可能方式的计数).如果添加,每次都会使npath的复杂性增加一倍.纯粹基于计算ifs我的复杂度为64,这太高了!循环也会增加npath的复杂性,因此函数的实际复杂度指标可能远远高于此值.

如果它是一个较小的简单函数的集合,那么更改像你给出的那个函数变得更加重要,因为很难做出特定的改变来实现预期的新行为而不会产生不必要的连锁效应.当然,您可以使用单元测试来确保不会发生这种情况,但是由于npath复杂度很高,您必须编写的测试数量以确保功能的功能完全覆盖非常大.

一般的经验法则:

  • 如果一个功能的身体不能适合你的屏幕,那么它可能也不适合你的头脑.避免使用比编辑器窗口更长的函数.您永远不必滚动查看功能的全部内容.
  • 你得到每个功能2 ifs.不仅如此,npath的复杂性也开始变得无法管理.
  • 功能应该做好一件事.试图成为所有交易的杰克的函数在每种情况下都可能无法正确.此外,函数尝试承担的责任越多,函数就越难以履行其所承担的所有职责.
  • 小功能可重复使用,大功能则不可重复使用.
  • 以一切圣洁的名义,评论您的代码!其他人几乎不可能看到你的功能并弄清楚它的意图.打破它并遵循早期的指导方针会有很大帮助,但即使这样,计算机代码也不如向普通英语表达其他人的想法那么好.评论澄清了一些可能不是一目了然的问题,可以帮助其他程序员在设计和实现代码时弄清楚你脑子里的内容.它们在执行时间方面没有任何成本,因此没有理由不发表评论.如果你单独留下这些代码并在一年的时间内再次回顾它,我可以保证你在编写它时永远不会弄明白你在想什么.

一个更好的解决方案是实现一个类,它提供了一系列方法所需的服务.

一个更好的解决方案是通过内置的功能来检查这个PHP可以做多少.由于我无法真正理解你的功能,我无法确定PHP是否已经完成了你需要这个功能所做的事情,但我怀疑它的很大一部分已经在PHP中实现了.

  • 如果一个功能的身体不能适合你的屏幕,那么它可能也不适合你的头部. (3认同)