Globals kötü!

6 Cevap php

Benim veritabanına $ linki ayarı ben bir GLOBAL kapsamı kullanmak gereken bir şey olurdu? Küresel kapsamı içinde tek değişken akıllıca olacaktır sahip sanki (fonksiyonları çok) benim ortamda ... görünüyor.

Ben şu anda bu yüzden bu şekilde ben küresel kapsamda bu yok ileri geri aktarmak için fonksiyonları kullanıyorum. Ama benim komut dosyası için bir engel bir parçasıdır.

Bildiriniz.

6 Cevap

Bunu gerçekleştirmek için en iyi yolu, bir işlevi var zaten küresel olarak kullanmaktır.

function getDB()
{
   global $Database;
   Return $Database;
}

Sonra uygulama kullanımı boyunca

getDB()->query(...)

Ya sizin sadece o kaynak çağrı eğer

mysql_query(...,getDB());

Şahsen, ben veritabanı Singleton desen mantıklı bir yer olduğunu düşünüyorum. Test fanatikleri benimle hemfikir olabilir, ancak bu durumda benim için çok mantıklı.

$db = DB::get();
$db->query('select ...');

Globals yerine singleton deseni kullanmak çok kötü.

  <?php
  class Singleton
  {
      static private $instances = array();

      static public function getInstance($className)
      {
          if (!isset(self::$instances[$className])) {
              self::$instances[$className] = new $className();
         }
         return self::$instances[$className];
     }
 }
 require_once 'DB.php';
 $db = Singleton::getInstance('DB');
 $db->query("select * .......");
?>

Eğer gerçekten onlara ihtiyacınız olduğunda her zaman işlevleri içinde küresellerle erişebilirsiniz.

function use_that_link() {
    global $link;
    var_dump($link);
}

Ama etrafında geçerek ne olursa olsun, muhtemelen daha iyi bir uygulamadır. Sadece doğrudan veritabanı erişimi kullanan herhangi bir fonksiyonu ilk parametre olarak veritabanı bağlantı alır ve gitmek için iyi olması gerektiğini unutmayın. (OOP size daha temiz bir çözüm sunabilir, ancak bu noktada bu yola girişim istemiyorum gibi geliyor.)

Bir daha pragmatik bir yaklaşım: ilkel namespacing

$GLOBALS['mydomain.com']['db'] = ...;

Sen küresellerle erişim ve mutasyona için bir sarıcı sınıfı yapabilirsiniz

Class Globals {

  private $domain = 'mydomain.com';

  function get($key)
  {
    return $GLOBALS[$this->domain][$key];
  }

  function set($key,$value)
  {
    $GLOBALS[$this->domain][$key] = $value;
  }

}
class Registry
{
    /*
        * @var array Holds all the main objects in an array a greater scope access
        * @access private
    */
    private static $objects = array();

    /**
        * Add's an object into the the global
        * @param string $name
        * @param string $object
        * @return bool
    */
    public static function add($name,$object)
    {
        self::$objects[$name] = $object;
        return true;
    }

    /*
        * Get's an object out of the registry
        * @param string $name
        * @return object on success, false on failure
    */  
    public static function get($name)
    {   if(isset(self::$objects[$name]))
        {
            return self::$objects[$name];
        }
        return false;
    }

    /**
        * Removes an object out of Registry (Hardly used)
        * @param string $name
        * @return bool
    */
    static function remove($name)
    {
        unset(self::$objects[$name]);
        return true;
    }

    /**
        * Checks if an object is stored within the registry
        * @param string $name
        * @return bool
    */
    static function is_set($name)
    {
        return isset(self::$objects[$name]);
    }
}`

Bunu gibi kullanabilirsiniz.

require_once 'classes/registry.class.php';

require_once 'classes/database/pdo.class.php';
Registry::set('Database',new Database);

Sonra her yerde Uygulama bunu gibi yapabilirsiniz:

function addPost(String $post,Int $id)
{
    $statement = Registry::get('Database')->prepare('INSERT INTO posts VALUES(:d,:p)');
    $statement->bindValue(':p',$id,PDO::PARAM_INT);
    $statement->bindValue(':p',$post);
}

Bu size bir çok Büyük kapsamı verecektir!