2016-12-04 15 views
2

私はJavaプログラミングから来ており、PHPのOOPスタイルのプログラミングに私の知識を適用しようとしています。致命的なエラー:クラスCLASSNAMEのエラーを既に再試行できませんでした。require_once()

データベースに接続するための静的メソッドをJavaで作成するのと同じように、データベースに接続するためのユーティリティクラスを作成しようとしました。

しかし、時間を費やしても、私はまだエラーを修正できません。

DBHelper.php

<?php 

class DBHelper 
{ 
    protected $db_name = 'myDb'; 
    protected $db_user = 'root'; 
    protected $db_pass = ''; 
    protected $db_host = 'localhost'; 

    public function obtainConnection() 
    { 

     $mysqli_instance = new mysqli($this->db_host, $this->db_user, $this->db_pass, $this->db_name); 

     /* check connection */ 
     if (mysqli_connect_errno()) { 
      printf("Connect failed: %s\n", mysqli_connect_error()); 
      exit(); 
     } 
     return $mysqli_instance; 
    } 
} 
?> 

私はと呼ばれる別のファイルにそれを使用しようとした後

このファイルにはエラーはありませんlogin.php

login.php

<?php 
if (isset($_POST['submit'])) { 
    include "/DBUtility/DBHelper.php"; 
    $username = $_POST['username']; //s means string 
    $password = $_POST['password']; // s means string 
    echo "<br/> Username value: " . $username; 
    echo "<br />Password value: " . $password; 
} 

if (empty($username) || empty($password)) { 
    echo "Fill out the fields!"; 
} else { 

    //PREPARE THE PreparedStatment or Stored Procedure 


    $dbHelper = new DBHelper(); 
    $connection = $dbHelper->obtainConnection(); 
    $preparedStatement = $connection->prepare('CALL getUserRoleByLogin(?, ?)'); //getUserRoleByLogin() is the name of stored proc in mysql db 
    $preparedStatement->bind_param('ss', $username, $password); //assign arguments to ? ? 
    $preparedStatement->execute();//execute the stored procedure. This will return a result 

    $userRole = $preparedStatement->store_result(); 
    $countOfRows = $preparedStatement->num_rows; 

?> 

Fatal error: Cannot redeclare class CLASSNAMEエラーに関するすべての関連質問を読みました。私はinclude("DBHelper.php"); の代わりにrequire_once("DBHelper.php");を使用する多くの指示に従ってみましたが、それでもエラーを取り除くことはできません。

私はobtainConnection()を静的にしてみて、DBHelper::obtainConnection();経由で電話しましたが、運はありません。同じエラーメッセージ。

私は、私はあなたがこれで私を助けることができると思いますclass DBHelper{

のブレースを開くにエラーが発生します。

ありがとうございます。 PHPでOOPを行う際に、あなたがやるべき

+0

さて、あなたは 'require_once'または' include_once'を行うことが正しいです。 "DBHelper"をレッドクレイアできないとか、クラス名は何ですか? – Rasclatt

+0

@Rasclattまずは、ありがとう。はい、私はエラーが発生します致命的なエラー:クラスを再宣言できませんDBHelper – p3ace

+0

これは他の理由がある可能性があります1)あなたは別の場所(おそらく他の誰かによって作成されたクラスと同じ名前を使用しています。 2)名前を変更して拡張するためにこのファイルを複製し、重複ファイルのクラス名を変更するのを忘れたのかもしれません。 – Rasclatt

答えて

2

カップルのヒント:

1)私は多分直接あなたのクラスにデシベルの資格情報を焼いていないについて再考ならば、それは、UIを介してそれらを変更することが困難/より面倒になりあなたはラインの下でUI制御機構を実装したいと思っていました。代わりに、define、またはjsonのprefファイル、または動的に作成されたphpファイルにそのような配列を含むファイルを作成してみてください。

/config.php

# You can create a series of defines including the database 
define('DB_HOST','localhost'); 
define('DB_NAME','dbname'); 
define('DB_USER','root'); 
define('DB_PASS','dbpassword'); 
# To maximize compatibility it's helpful to define fwd/back slash 
define('DS',DIRECTORY_SEPARATOR); 
# It is helpful to create path defines for easy file inclusion 
define('ROOT_DIR',__DIR__); 
define('CLASSES',ROOT_DIR.DS.'classes'); 

# Start session 
session_start(); 

2)その後、手動/含める必要はありませんすることができますconfig.phpファイル内のクラスautoloaderを作成します。私はそれを証明するのが最も簡単ですので、定義を行いますページにクラスが必要です。それは自動的に含まれます:私はあなたが新しい接続を作成しないようにするたびに、静的な接続を作成するつもりです

spl_autoload_register(function($class) { 
    if(class_exists($class)) 
     return; 

    # This will turn a namespace/class into a path so should turn: 
    # $db = new \DBUtility\DBHelper(); 
    # into: 
    # /var/www/domain/httpdocs/classes/DBUtility/DBHelper.php 
    $path = str_replace(DS.DS,DS,CLASSES.DS.str_replace('\\',DS,$class).'.php'); 
    # If the class file is located in the class folder, it will include it 
    if(is_file($path)) 
     include_once($path); 
}); 

3)(また、私は)PDOを使用します。

/クラスを/ DBUtility/DBHelper。PHP

<?php 
namespace DBUtility; 

class DBHelper 
{ 
    protected $query; 
    private static $con; 

    public function connection() 
    { 
     # This will send back the connection without making a new one 
     if(self::$con instanceof \PDO) 
      return self::$con; 
     # I like to catch any pdo exceptions on connection, just incase. 
     try { 
      # Assign the connection 
      self::$con = new \PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME,DB_USER,DB_PASS); 
     } 
     catch(\PDOException $e) { 
      # Here you can just die with a more user-friendly error. 
      # It would be helpful to save the actual error to a log file 
      $msg = $e->getMessage(); 
      # I would put your log outside the root or in a protected folder 
      $txt = realpath(ROOT_DIR.DS.'..').DS.'errors'.DS.'sql.txt'; 
      # Make a directory if none set 
      if(!is_dir(pathinfo($txt,PATHINFO_DIRNAME))) { 
       # Make the directory 
       if(mkdir(pathinfo($txt,PATHINFO_DIRNAME),0744,true)) { 
        # Save to log file 
        file_put_contents($txt,$msg.PHP_EOL); 
       } 
      } 
      else { 
       # Save to log file 
       file_put_contents($txt,$msg.PHP_EOL); 
      } 

      die("Site is under maintenance."); 
     } 
    } 
    # It would be helpful to create a query that will bind and not bind 
    public function query($sql,$bind = false) 
     { 
      if(is_array($bind)) { 
       foreach($bind as $key => $value) { 
        $sKey = ":{$key}"; 
        $bindArr[$sKey] = $value; 
       } 

       $this->query = $this->connection()->prepare($sql); 
       $this->query->execute($bindArr); 
      } 
      else { 
       # The second "query" on this is the method from PDO, not the 
       # "query" method from this class 
       $this->query = $this->connection()->query($sql); 
      } 

      return $this; 
     } 

    public function getResults() 
     { 
      if(empty($this->query)) 
       return false; 

      while($result = $this->query->fetch(\PDO::FETCH_ASSOC)) { 
       $row[] = $result; 
      } 

      return (isset($row))? $row : false; 
     } 
} 
# If your page ends with a php tag, you should just remove it. It will 
# protect against empty spaces that may cause "header already sent" errors 

3A)私はオートロード機能に次のようなものを使用します。

/classes/Helper.php

class Helper 
    { 
     public static function autoload($function) 
      { 
       if(function_exists($function)) 
        return; 

       $path = ROOT_DIR.DS.'functions'.DS.$function.'.php'; 
       if(is_file($path)) 
        include_once($path); 
      } 
    } 

4)/便利/再利用可能な機能やクラスを作成します。メソッド

/functions/getUserRole.php

function getUserRole($username,$password,\DBUtility\DBHelper $DBHelper) 
    { 
     return $DBHelper->query('CALL getUserRoleByLogin(:0, :1)',array($username,$password))->getResults(); 
    } 

/index.php

# Include the config file 
require_once(__DIR__.DIRECTORY_SEPARATOR.'config.php'); 

if (isset($_POST['submit'])) { 
    # No need for this line ->> include "/DBUtility/DBHelper.php"; 
    # Use trim to remove empty spaces on the left and right 
    $username = trim($_POST['username']); 
    $password = trim($_POST['password']); 
} 

if (empty($username) || empty($password)) { 
    echo "Fill out the fields!"; 
} else { 
    # User our function autoloader to include this function 
    Helper::autoload('getUserRole'); 
    # Use the function and inject the DB class 
    $userRoles = getUserRole($username,$password,new \DBUtility\DBHelper()); 
    $count  = count($userRoles); 

    echo "Count: {$count}"; 
    echo '<pre>'; 
    print_r($userRoles); 
    echo '</pre>'; 
} 
+0

すべてのヒントをありがとう。私はPHPでプログラミングのOOPの方法を学び続けているので、これらはすべて将来的に役立つでしょう。あなたは実際に正しいです、私はエラーを修正するためにrequire_onceと共に名前空間を使用しなければなりませんでした。私はあなたが与えた例を勉強するつもりです。 OOPのパターンとスタイルのほとんどは、Javaでのやり方と似ています。私が学ぶ必要のあるキーワードとコマンドがあります。再度、感謝します。私の問題は名前空間を使って解決しました。 – p3ace

+0

うまくいけば、この資料のいくつかは役に立ちます、私はいくつかの追加部分を追加しました、私はいくつかのケースでは、非常によく、またはまったく何かに対処していない気づいた。乾杯 – Rasclatt

関連する問題