Использование Singleton для создания единого MySQLi Connection и использование его для нескольких объектов? - PullRequest
1 голос
/ 18 декабря 2010

Всем доброго утра!

Я не совсем новичок в PHP, как и сам, но все же немного нов, когда дело доходит до ОО с PHP5.Теперь я подумал об этом крошечном проекте, где я хотел использовать HTML5 и немного OO PHP.Это должен быть горизонтальный прокручиваемый график времени один день.

Поэтому я создал класс Временная шкала .Это мой главный объект.Среди других методов, один метод ( $ timeline-> createYearString (); ) состоит в создании моей строки лет.Я реализовал другой класс Year , который метод createYearString (); вызывает X раз для создания вывода HTML моих лет.

Для заполнения моеголет с фактами, мне нужно подключение к базе данных.Будучи новичком в oop-подходе к соединениям mysql, я обыскал и нашел комментарий Атли (http://www.dreamincode.net/forums/topic/81496-connection-to-the-mysql-using-oop/page__view__findpost__p__1038512) о синглтоне mysqli. Я реализовал его и попытался использовать его в объекте класса Year . Забавная вещь, $ dbLink возвращается для первого объекта, но не для второго, который создается мгновенно точно так же, как первый. $ this-> db неожиданно возвращает NULL во второй год, и поэтому я получаю не-объектная FATAL ошибка из PHP

См. мои три класса ниже. Что я пропускаю?

class Year {
 private $year;
 private $db;

 function __construct($year) {
  $this->year=$year;
  $this->db=MyDB::Get();
 }

 function createHTML($last='') {
  $out=" <div class=\"year_outer".(($last) ? ' last_year' : '')."\" id=\"y".$this->year."\">
     <div class=\"year_inner\">
      <div class=\"year_above\">
       <span class=\"yearnr\">".$this->year."</span>
      </div>
      <div class=\"year_below\"></div>
     </div>
     <div class=\"months_wrapper\">\n";
  if(!$last) {
   for($i=1; $i<=12; $i++) {
    $fDoM = mktime(0,0,0,$i,1,$this->year);            // $fDoM = first Day of Month
    $lDoM = mktime(0,0,0,$i,date('t',mktime(0,0,0,$i,1,$this->year)),$this->year);  // $lDoM = last Day of Month
    $sql = $this->db->query("SELECT * FROM tp_together");
    //echo date('d.m.Y',$fDoM)." bis ".date('d.m.Y',$lDoM)."\n";

    $out.= " <div class=\"month_outer_l\" id=\"".$this->year."-".$i."\">
        <div class=\"month_outer_s\">
         <div class=\"month_inner\"><span>".date("M",mktime(0,0,0,$i,1,$this->year))."</span></div>
        </div>
       </div>\n";
    } 
  }  
  $out.= " </div>
    </div>\n";

  return $out;
 }
}

class Timeline {
 public $daysDating;
 public $startYear;
 public $endYear;
 public $numberOfYears;

 function __construct($start,$end='') {
  $this->startYear = $start;
  $this->endYear  = ($end=='') ? date("Y")+1 : $end;
  $this->daysDating = $this->calcDaysDating();
  $this->numberOfYears= $this->calcNumberOfYears();
 }

 function createYearString() {
  $x=new Year('2004');
  print $x->createHTML();
  $y=new Year('2005');
  print $y->createHTML();
  $z=new Year('2006');
  print $z->createHTML(true);

  // $j=$this->endYear;
  // for($i=$this->startYear; $i<=$j; $i++) {
  //  $x=new Year($i);
  //  ($i==$j) ?
  //   print $x->createHTML(true) :
  //   print $x->createHTML();
  // }
 }

 private function calcDaysDating() {
  $today=mktime(0,0,0,date("m"),date("d"),date("y"));
  $day1=mktime(0,0,0,7,11,2006);

  return $today-$day1;
 }

 private function calcNumberOfYears() {
  return $this->endYear - $this->startYear +1;
 }

 function createHNavigation() {
  $x=1;
  $out='<ul>';
  for($i=$this->startYear; $i<=$this->endYear; $i++) {
   $out.="<li><a class=\"navBubble\" id=\"navBubble$i\" accesskey=\"$x\" href=\"#y$i\" title=\"Go to $i\"></a></li>\n";
   $x++;
  }
  $out.="</ul>";
  return $out;
 }
}

class MyDB {
 private static $dbLink;

 private function __construct() {}
 private function __clone() {}

 public static function Get() {
  if(!self::$dbLink) {
   self::$dbLink = new mysqli(DB_HOST, DB_USER, DB_PWD, DB_NAME);
   if(mysqli_connect_errno()) {
    throw new Exception("Database connection failed: ".mysqli_connect_error());
   }
   return self::$dbLink;
  }
 }
}

На случай, если я не прояснил свою проблему. $ x напоминает 2004 ($ x= новый год ('2004')), который работает нормально. Но тогда фолдинг $ y ($ y = новый год ('2005)) возвращает ФАТАЛЬНУЮ ОШИБКУ, а $ this-> db возвращает NULL - ПОЧЕМУ?

Большое спасибо, ваша помощь очень ценится.

Ответы [ 2 ]

1 голос
/ 18 декабря 2010
public static function Get() {
  if(!self::$dbLink) {
  self::$dbLink = new mysqli(DB_HOST, DB_USER, DB_PWD, DB_NAME);
  if(mysqli_connect_errno()) {
   throw new Exception("Database connection failed: ".mysqli_connect_error());
  }
  //was here
  }
   return self::$dbLink; //should be here
 }
1 голос
/ 18 декабря 2010

Ваша функция MyDB :: Get не возвращает self :: $ dbLink в случае, если она уже установлена.

возвращает в оригинале:

public static function Get() {
    if(!self::$dbLink) {
        self::$dbLink = new mysqli(DB_HOST, DB_USER, DB_PWD, DB_NAME);
        if(mysqli_connect_errno()) {
            throw new Exception("Database connection failed: ".mysqli_connect_error());
        }
        return self::$dbLink;
     }
}

возвращает, чтобы она работала:

public static function Get() {
    if(!self::$dbLink) {
        self::$dbLink = new mysqli(DB_HOST, DB_USER, DB_PWD, DB_NAME);
        if(mysqli_connect_errno()) {
            throw new Exception("Database connection failed: ".mysqli_connect_error());
        }
     }
     return self::$dbLink;
}

(PS, если для отступа использовать более одного символа, это будет намного легче обнаружить.)

...