オブジェクト指向について

このQ&Aのポイント
  • オブジェクト指向についての質問
  • データベース接続関連のクラスに記述された処理が正しいか
  • オブジェクト指向の呼び出し方を指導してほしい
回答を見る
  • ベストアンサー

オブジェクト指向について

連続質問で誠に恐縮ですが投稿させて頂きました。 もしTo_aru_User様が拝見したらご協力いただければと思います。 以前の質問でオブジェクト指向で件数の表示とページングの質問をさせて頂きました。 public function getComments($page) {      // 必ず1以上の整数になるようにする   $page = max(1, (int)$page);      // 開始オフセット   $offset = COMMENTS_PER_PAGE * ($page - 1);      // SQL実行   $stmt = $this->pdo->query(sprintf(     implode(' ', array(       'SELECT CALC_FOUND_ROWS *',       'FROM `comments`',       'LIMIT %d, %d',     )),     $offset,     COMMENTS_PER_PAGE   ));      // コメントを取得   $comments = $stmt->fetchAll();      // 現在件数を取得   // (PDOのコンストラクタでMYSQL_ATTR_USE_BUFFERED_QUERYを   // 有効化しているときだけSELECTに対してrowCountメソッドが使える)   $current_count = $stmt->rowCount();      // 総件数を取得   $whole_count = (int)$this->pdo->query('SELECT FOUND_ROWS()')->fetchColumn();      // メッセージ作成   $message = sprintf('全%d件中、%d件から%d件まで表示しています',     $whole_count,     $offset + 1,     $offset + $current_count   );      // 情報を連想配列で返す   return array(     'comments' => $comments,     'message' => $message,   );    } この記述はデータベース接続関連のクラスの中(DB.php)に記述したのですが正解でしょうか? またそれをindex.phpで呼び出そうとしてもうまくいきません。 申し訳ないのですがオブジェクト指向の呼び出しかたを指導していただけませんでしょうか? オブジェクト指向をこのご質問と合わせて勉強しようと思ったのですがPHPも覚えたてでアタフタ状態なので、今回の件をとりあえずちゃんと解決してから基礎からしっかり固めようとおもいます。 大変申し訳ございませんが、お力をお貸しいただけませんでしょうか。 よろしくお願いいたします。

  • PHP
  • 回答数7
  • ありがとう数14

質問者が選んだベストアンサー

  • ベストアンサー
noname#244856
noname#244856
回答No.7

ページングリンクを表示したければ // 総ページ数を取得 $max_page = ceil($whole_count / COMMENTS_PER_PAGE); // ページラベルを格納する配列 $labels = array(); // 1ページずつラベルを生成 for ($i = 1; $i <= $max_page; $i++) {   $labels[] = $i !== $page ?     "<a href=\"?page={$i}\">{$i}</a>" : // 現在以外のページ     (string)$i // 現在のページ   ; } // ページラベルを「 | 」区切りで結合してまとめる $labels = implode(' | ', $labels); として変数$labelsを用意し、それをメソッドが返す連想配列に入れてみてはどうでしょうか? bankのテーブルに登録されなかったのは何故でしょうね・・・提示していただいたコードにはこれといってミスは無いように思えます。 try {      // トークンをチェック   Token::check($token);   // 登録   DB::connect()->signup($name, $email, $password);   DB::connect()->bankup($no, $bank, $bankshi, $bankba, $bankme);   // ログインページに遷移   redirect('/login.php');    } catch (Exception $e) {      // 例外スタックを配列に変換   $errors = exception_to_array($e);    } という流れで何も例外がキャッチされずにそのままログインページに遷移出来ているならば、SQL実行には成功しているはずです。「既にログイン済みなのでTryブロックに入る前にindex.phpに飛ばされている」というケースが考えられますが、新規登録フォームはちゃんとブラウザで表示でき、それで送信したあとにsignupメソッドは正常に稼働しているんですよね?そうであればちょっと思い当たる節はないですね・・・すみません・・・ なお、「signup」と「bankup」という2つの連続する処理で、signupだけ成功してbankupは失敗すると普通はsignupも無かったことにしたい、と考えますよね?そういった処理を実現するのが「トランザクション処理」です。 トランザクション(transaction) [e-Words] http://e-words.jp/w/E38388E383A9E383B3E382B6E382AFE382B7E383A7E383B3.html PDOは簡単にトランザクションを行うことが出来ます。 PDO::beginTransaction http://php.net/manual/ja/pdo.begintransaction.php PDO::commit http://www.php.net/manual/ja/pdo.commit.php PDO::rollback http://www.php.net/manual/ja/pdo.rollback.php PDO::lastInsertId (最後に生成されたAUTO_INCREMENTの値を返す。マニュアルには直接記載されていないが、コメント欄にある通りMySQLではトランザクション処理中だけ使える。) http://php.net/manual/ja/pdo.lastinsertid.php ひとつ気になったのですが、$noってsignupで自動生成された会員番号のことですよね?でしたらPDO::lastInsertIdも用いて下記のようにしてみてはいかがですか。signupとbankupは必ず同時に起こるアクションなので、signup_and_bankupというラッパーメソッドをpublicで作っておき、signupとbankupはprivateにして外部から呼び出さないものとしましょう。 【DB.php】 public function signup_and_bankup($name, $email, $password, $bank, $bankshi, $bankba, $bankme) {      // トランザクション開始   $this->pdo->beginTransaction();      try {          // 会員情報の登録     $this->signup($name, $email, $password);     // 生成された会員番号を取得     $no = $this->pdo->lastInsertId();     // 口座情報を登録     $this->bankup($no, $bank, $bankshi, $bankba, $bankme);     // 一連の処理が全て成功すればコミット     $this->pdo->commit();        } catch (Exception $e) {          // 1つでも失敗が起こればロールバック     $this->pdo->rollback();     // 例外はここでは処理しないのでもう一度投げる     throw $e;        }    } private function signup(...) { } private function bankup(...) { } 【index.php】 try {      // トークンをチェック   Token::check($token);   // 登録   DB::connect()->signup_and_bankup($name, $email, $password, $bank, $bankshi, $bankba, $bankme);   // ログインページに遷移   redirect('/login.php');    } catch (Exception $e) {      // 例外スタックを配列に変換   $errors = exception_to_array($e);    } filter_struct_utf8に続いてsignup_and_backupでも全く同じ並びの引数なのに2回も渡すのを煩わしく思うならば、filter_struct_utf8の返り値をextractせずに $params = filter_struct_utf8(....); のようにそのまま配列に入れておき、 // 登録 call_user_func_array(array(DB::connect(), 'signup_and_bankup'), $params); とする手もあります。(filter_struct_utf8とsignup_and_backupの引数の順番が一致するように注意してください。キーの値は無視され、単に並んでいる値の順番だけがそのまま引数の順番として扱われます。) call_user_func_array http://php.net/manual/ja/function.call-user-func-array.php call_user_func_arrayの第1引数に渡すcallableという擬似変数型について(今回のケースはこのタイプ3に該当) http://www.php.net/manual/ja/language.types.callable.php 脳内デバッグしかしてないので細かいミス等ありましたらすみません m(_ _)m

milkkokoa94856
質問者

お礼

大変丁寧に教えていただきましてありがとうございました!! 本当に勉強になりましたm(_ _)m 登録できなかったのは私の何かのミスだと思うのでテーブル名など記述間違いを探してみます。 ご質問全てに丁寧に教えて頂きやる気も出てきました♪ オブジェクト指向を頑張って覚えたいと思います。 またご質問にこのサイトを利用させていただくとおもいますので、ご縁がございましたら是非よろしくお願いいたします。 この度はありがとうございました。

その他の回答 (6)

noname#244856
noname#244856
回答No.6

// 情報を連想配列で返す return array(   'comments' => $comments,   'message' => $message, ); としているので <p><?=h($result['comment'])?></p> ではなく <p><?=h($result['message'])?></p> ですね。

milkkokoa94856
質問者

補足

ありがとうございました。 $offset = COMMENTS_PER_PAGE * ($page - 1); のような記述あったもので勝手に次のページへなどの機能も表示できるものと勘違いしておりました。 ページを変えるようなものは別途記述が必要ということですね。 messageでは無事に件数を表示できました。 長々とお付き合い頂き誠にありがとうございました>< おまけ程度にご回答頂けると幸いなのですが、ドットインストールで登録する際に、テーブルごとにINSERTでいれていたのですが、オブジェクト指向の場合は public function bankup($no, $bank, $bankshi, $bankba, $bankme) { // 例外初期化 $e = null; // 登録チェック if ($no === '') { $e = e('会員番号が入力されていません。', $e); } if ($bank === '') { $e = e('銀行名が入力されていません。', $e); } if ($bankshi === '') { $e = e('支店名が入力されていません。', $e); } if ($bankba === '') { $e = e('口座番号が入力されていません。', $e); } if ($bankme === '') { $e = e('口座名義が入力されていません。', $e); } // 1つでも例外が発生していればスローする if ($e) { throw $e; } // プリペアドステートメントを生成 $stmt = $this->pdo->prepare(implode(' ', array( 'INSERT', 'INTO `bank`(`no`, `bank`, `bankshi`, `bankba`, `bankme`)', 'VALUES (?, ?, ?, ?, ?)', ))); // 値をバインドして実行 $stmt->execute(array($no, $bank, $bankshi, $bankba, $bankme)); } このような形でクラスにユーザーテーブルとは別に記述して signup.phpで extract( に追加して // POSTされたときのみ実行 if ($_SERVER['REQUEST_METHOD'] === 'POST') { try { // トークンをチェック Token::check($token); // 登録 DB::connect()->signup($name, $email, $password); DB::connect()->bankup($no, $bank, $bankshi, $bankba, $bankme); // ログインページに遷移 redirect('/login.php'); } catch (Exception $e) { // 例外スタックを配列に変換 $errors = exception_to_array($e); } } というふうに追加してやってみたものの会員の方には登録されたのですが、bankのテーブルには登録されませんでした。 会員登録のとこをコピーしたりして自分なりに試してはみたのですがなぜかbankテーブルの方だけ登録がされずアレレとなってしまいました。 追加質問のようで恐縮なのですが、せっかく大先生にお会いできたので解決のヒントになるかと思いご質問させていただきました。

noname#244856
noname#244856
回答No.5

SQLにシンタックスエラーがあると言ってます。 'SELECT CALC_FOUND_ROWS *', ↓ 'SELECT SQL_CALC_FOUND_ROWS *', またミスでした・・・トホホ・・・

milkkokoa94856
質問者

補足

ありがとうございました!! ついに一覧を取得し表示することができました。 しかしながら最後の <p><?=h($result['comment'])?></p> ここがエラーになっており Notice: Undefined index: と出ております。 この部分は次のページへなどの部分が表示されるばしょなのでしょうか? 辿っていくとそのようなページかと思っているのですが、このリンクの部分が今だにエラーで夜が明けてしまいましたm(_ _)m 記載させて頂いたエラーでは原因を突き止めるのが難しいとは思いますが、調べて見る箇所などヒントがありましたらアドバイス頂きたくしつこくご質問させていただきました。

noname#244856
noname#244856
回答No.4

PDO::MYSQL_ATTR_INIT_COMMAND => 'SET CHARACTER SET utf8' の件に関してはこちらをご覧になられたのでしょうか? 【PHP, PDOでMySQL接続時の文字コード設定】 http://me.beginsprite.com/archives/889 実はこれ、コンストラクタの初期化クエリで実行したところで通常クエリで実行したのと何も変わらないんですよね。「SET NAMES」と「SET CHARACTER SET」もほとんど変わりません。むしろ後者はお節介なことをしようとするので前者の方が推奨されます。下記で詳しく解説しています。 【PHPでデータベースに接続するときのまとめ】 http://qiita.com/mpyw/items/b00b72c5c95aac573b71 上記のページでもリンクを張っていますが、古いPHPのレンタルサーバーであれば以下のような方法を採ることが出来ます。 【PHP 5.3.6より前のバージョンの PDO MySQL で charset を指定する】 http://qiita.com/ngyuki/items/d88a4df860abb51eb714 cnfファイル設置が面倒であれば、妥協して「SET NAMES utf8」でもいいかもしれません。非常に稀な環境での例外もありますが、基本的にはUTF-8に限り「SET NAMES」の安全性が保証されています。 でもさくらのスタンダードプランってバージョン選べるんじゃないですかね。5.2~5.4で選択出来ると思いますが。5.4以降限定の機能がそれなりに多いので、5.4系の最新バージョンを使えるならそれを使っておくべきだと思います。可能であればジェネレータやfinally構文も使える5.5系の方が望ましいですが。 endforeachのエラーに関しては、 <?php foreach ($result['comments'] as $comment) ?> ↓ <?php foreach ($result['comments'] as $comment): ?> で解決します。私の入力ミスでした、申し訳ないです。 制御構造に関する別の構文 http://php.net/manual/ja/control-structures.alternative-syntax.php オブジェクト指向は誰もがぶち当たる壁なのでめげずに頑張ってください! (実を言うとPDO自体もオブジェクト指向なんですけどね)

milkkokoa94856
質問者

補足

素早い回答ありがとうございます。 :がないということに気がつかない私がダメですね>< とりあえずエラー文は消えたのですが・・・ Internal Server Errorが出てしまいました。 このエラーばっかりは自分で解決するしかないかなと思いながら質問を追加してしまいました。 URLが error.php?errors[0]=SQLSTATE[42000]%3A+Syntax+error+or+access+violation%3A+1064+You+have+an+error+in+your+SQL+syntax%3B+check+the+manual+that+corresponds+to+your+MySQL+server+version+for+the+right+syntax+to+use+near+'FROM+`users`+LIMIT+0%2C+15'+at+line+1 となってるがヒントになるのでしょうか? これだけ色々アドバイスを頂き応援してくださっているので何とか今回の件を終了させ頑張って覚えたいと思います><

noname#244856
noname#244856
回答No.3

「1個しかインスタンス作れないならそもそも全部静的メソッド・静的プロパティにすればいいじゃん!」と思うかもしれませんが、そうしちゃうと、connect(新しくPDOインスタンスを生成するメソッド)を呼ぶ前にgetCommentsを呼べてしまいますよね。getCommentsはPDOインスタンス生成が済んでいることが前提のメソッドなので、そうしてしまうといくらか不都合があるわけです。そこでシングルトン形式を採用することで、あらゆるメソッドを呼ぶためには必ずPDOインスタンス生成を通過しなければならないように強制しています。

noname#244856
noname#244856
回答No.2

静的なメソッド(staticのついているもの)は クラス名からスコープ定義演算子「::」を用いてアクセスします。 動的なメソッド(staticのついていないもの)は インスタンスからアロー演算子「->」を用いてアクセスします。 DBクラスはシングルトンを実現するために、自分自身の動的インスタンスを自分自身の静的プロパティに格納するというちょっと珍しいことをやっていますが、分かりやすく画像にすればこんな感じでしょうか。

noname#244856
noname#244856
回答No.1

>> この記述はデータベース接続関連のクラスの中(DB.php)に記述したのですが正解でしょうか? はい、正しいですよ。 extract(filter_struct_utf8(INPUT_GET, array(   'page' => '', ))); try {   $result = DB::connect()->getComments($page); } catch (Exception $e) {   error_page($e); } のように変数$resultに取得して、あとはHTML部の中で、 <?php if ($result): ?>  <ul> <?php foreach ($result['comments'] as $comment) ?>   <li><?=h($comment['カラム名'])?></li> <?php endforeach; ?>  </ul> <?php endif; ?>  <p><?=h($result['comment'])?></p> みたいにすればいいんじゃないですかね。

milkkokoa94856
質問者

補足

いつも本当にお世話になります。 図をUPしながら説明していただき頭があがりません。 仕事から帰ってワクワクしながらやってみたのですが、できませんでした。 オブジェクト指向に向いていないのかと凹んできました。 index.phpには <?php // 初期化 require 'init.php'; // ログインされている状態を要求 require_login(); extract(filter_struct_utf8(INPUT_GET, array( 'page' => '', ))); try { // ログイン中のユーザー情報を取得 $me = DB::connect()->getUser($_SESSION['user_id']); // 全てのユーザー情報を取得 $all = DB::connect()->getAllUsers(); $result = DB::connect()->getComments($page); } catch (Exception $e) { // エラーページに遷移 error_page($e); } // 出力を開始 start_output(); ?> <?php include 'adheader.php'; ?> <?php if ($result): ?> <ul> <?php foreach ($result['comments'] as $comment) ?> <li><?=h($comment['name'])?></li> <?php endforeach; ?> </ul> <?php endif; ?> <p><?=h($result['comment'])?></p> </body> </html> DB.phpにはクラスの中にちゃんと public function getComments($page) { // 必ず1以上の整数になるようにする $page = max(1, (int)$page); // 開始オフセット $offset = COMMENTS_PER_PAGE * ($page - 1); // SQL実行 $stmt = $this->pdo->query(sprintf( implode(' ', array( 'SELECT CALC_FOUND_ROWS *', 'FROM `users`', 'LIMIT %d, %d', )), $offset, COMMENTS_PER_PAGE )); // コメントを取得 $comments = $stmt->fetchAll(); // 現在件数を取得 // (PDOのコンストラクタでMYSQL_ATTR_USE_BUFFERED_QUERYを // 有効化しているときだけSELECTに対してrowCountメソッドが使える) $current_count = $stmt->rowCount(); // 総件数を取得 $whole_count = (int)$this->pdo->query('SELECT FOUND_ROWS()')->fetchColumn(); // メッセージ作成 $message = sprintf('全%d件中、%d件から%d件まで表示しています', $whole_count, $offset + 1, $offset + $current_count ); // 情報を連想配列で返す return array( 'comments' => $comments, 'message' => $message, ); } と記述しました。 SQL文のところはusersの登録人数を読ませたいのでテーブルをusersに変えています。 あとレンタルサーバーがさくらサーバーのスタンダードを使用しておりPHPのバージョンが古いためオブジェクト指向を教えていただく前は PDO::MYSQL_ATTR_INIT_COMMAND => 'SET CHARACTER SET utf8')); を記述していました。 オブジェクト指向でもなにかこれの対策が必要なのでしょうか? 今出ているエラーは Parse error: syntax error, unexpected 'endforeach' (T_ENDFOREACH) in /home/アカウント/www/index.php on line 40 40行目には <?php endforeach; ?> が記述されています。 理解力がないので質問するのもご迷惑かと思いながらご質問させていただきました。

関連するQ&A

  • mysqlについてサンプルなど教えてもらえませんか

    すいません。今phpなどを使いウェブサイトを作っているのですが、データベースがどうしても 必要となり、参考サイトなどを見ながら作りました。 ほとんどできたのですが、最後に一部データベースの関数などでわからない事があり困っています。 (正直私はプログラムはphp程度が少し分かる程度で、データベースも単純な使い方しかしない 予定なので参考サイトをざっと見ただけでmysqlの事がほとんど分かりません) ググってそれらしい物を探してはいるのですが、私がやりたい事はデータベースから 件数を取りたいだけです。 取った件数をphpで表示したいのですが、何時間やっても良くわかりません。 申し訳ないんですが取り出した後その件数をphpのechoで表示するまでをサンプルとして書いてもらえませんか?(可能であれば「ここでこのような処理が行われている」とコメントがもらえると助かります) データベース関係はphpと違って初心者用のサイトなども無く、書いてある事がほとんど分かりません。 (ここでSELECT COUNT(*)を使うと教えてもらったのですが、SELECT COUNT(*)でググっても サンプルなども出てきません) $pdo = new PDO("mysql:dbname=aaa", "root"); $pdo->query("set names utf8;"); // ------------------------------------------------ $sql = $pdo->query("SELECT COUNT(*) FROM bbb"); $stmt = $pdo->query($sql); $stmt->execute(); $count=$stmt->rowCount(); echo $count; ----------------------------------------------- $result = mysql_query("SELECT COUNT(*) FROM bbb"); $row = mysql_fetch_assoc( $result ); echo $row;

    • ベストアンサー
    • MySQL
  • PHP,SQL,オブジェクト指向プログラミング

    こんにちは。僕は、現在、PHPとSQLとオブジェクト指向を用いて、掲示板を作成しています。 今ログインフォームまで完成しましたが、その中の認証処理でつまづいています。 ソースを載せますので、アドバイス等お願いします。 session_start(); include 'class.php'; include 'useclass.php'; $its=new keijibandatabase(); $its->k_conect(); $its->k_usertable(); $its2=new userdata; $its2->k_login(); function k_usertable() { //テーブルuserの呼び出し $sql = 'SELECT * FROM user'; $stmt=$this->pdo->query($sql); while($row = $stmt -> fetch(PDO::FETCH_ASSOC)){ } //データベースクラス function k_login() { //ユーザ認証 $row; $user=$_POST['user']; $pass=$_POST['pass']; if($user===$row['uid'] && $pass===$row['pass']){ echo "成功"; }else{ echo "失敗"; } } 以上です。 これらのコードは別々のファイルに記述されています。 回答よろしくお願いします

  • 【PHP】PDOでのMysqlから値を取り出す時に

    現在phpを勉強しております。 PDOオブジェクトを生成し、 prepareメソッドでMySQLで実行するクエリをセットして executeメソッドで実行する。 というのを以下のようにしております $pdo= new PDO($dsn, $user, $password); $query = "SELECT * FROM table_name"; $stmt = $pdo->prepare(); $stmt->execute; で、この場合でも正常に動くのですが MySQL内のテーブルに「?」が含まれる場合だと $query = "SELECT * FROM table_name?test"; $stmt = $pdo->prepare(); $stmt->execute; とすると$queryの「?」をバインド変数とみなしてしまい エラーで「?の数とバインド先の変数の数を合わせろ」と出てしまいます。 ですので、「?」をエスケープしようと思い $query = "SELECT * FROM table_name\?test"; としたのですが、結局エスケープされず 同じエラーが出てしまいました。 エスケープできるならエスケープの方法か ?をバインド変数としてみなさない方法か または他の解決方法かを よろしければご教授願います。

    • ベストアンサー
    • PHP
  • PDOがうまく動かない

    PDOがうまく動かなくて困っています。 $get_id = $_GET['id']; $stmt = $pdo->query("SELECT * FROM table where hoge = ':id'"); $stmt->bindValue(":id",$get_id, PDO::PARAM_STR); $stmt->execute(); if($row = $stmt->fetch()) { echo "あああ"; } $get_id = $_GET['id']; $stmt = $pdo->query("SELECT * FROM table where hoge = '$get_id'"); if($row = $stmt->fetch()) { echo "あああ"; } 2つ目は「あああ」と表示されるのですが、1つ目は何も表示されません。 よろしくおねがいします。

    • ベストアンサー
    • PHP
  • sql エラー

    エラーが出ます。どこかおかしな点はありますでしょうか。 エラー文 Call to a member function prepare() on a non-object ソース $page = 1; $limit = 2; $offset = $limit * ($page - 1); $sql='SELECT COUNT(*) FROM message WHERE memberid=? GROUP BY aid'; $stmt=$dbh->prepare($sql); $data[]=$memberid; var_dump($data); $stmt->execute($data); $dbh=null; $total=$stmt->fetchColumn(); $lastpage= ceil($total/$limit); $sql='SELECT aid,max(kaisyamei),max(day) FROM message WHERE memberid=? GROUP BY aid LIMIT '.$limit.' OFFSET '.$offset; $stmt=$dbh->prepare($sql); $stmt->execute($data); $dbh=null; ご教授お願いいたします。

    • ベストアンサー
    • MySQL
  • PHPでのページング処理についての質問です。

    ドットインストールにてページングの勉強をしています。 http://dotinstall.com/lessons/paging_php_v2/8510 件数が多いと、 この場合ですと10ページ以上まで表示されてしまうかと思うのですが、 よくあるWEBサービスのように10ページまでで区切り、 10ページ目をクリックすると、 5ページから15ページまでを表示させたいのですが、 どのように書いていくものでしょうか? <?php define('DB_HOST', 'localhost'); define('DB_USER', 'dbuser'); define('DB_PASSWORD', '********'); define('DB_NAME', 'dotinstall_paging_php'); define('COMMENTS_PER_PAGE', 5); if (preg_match('/^[1-9][0-9]*$/', $_GET['page'])) { $page = (int)$_GET['page']; } else { $page = 1; } error_reporting(E_ALL & ~E_NOTICE); try { $dbh = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME,DB_USER,DB_PASSWORD); } catch (PDOException $e) { echo $e->getMessage(); exit; } // select * from comments limit OFFSET, COUNT // page offset count // 1 0 5 // 2 5 5 // 3 10 5 // 4 15 5 $offset = COMMENTS_PER_PAGE * ($page - 1); $sql = "select * from comments limit ".$offset.",".COMMENTS_PER_PAGE; $comments = array(); foreach ($dbh->query($sql) as $row) { array_push($comments, $row); } $total = $dbh->query("select count(*) from comments")->fetchColumn(); $totalPages = ceil($total / COMMENTS_PER_PAGE); // var_dump($comments); // exit; $from = $offset + 1; $to = ($offset + COMMENTS_PER_PAGE) < $total ? ($offset + COMMENTS_PER_PAGE) : $total; ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>コメント一覧</title> </head> <body> <h1>コメント一覧</h1> <p>全<?php echo $total; ?>件中、<?php echo $from; ?>件~<?php echo $to; ?>件を表示しています。</p> <ul> <?php foreach ($comments as $comment) : ?> <li><?php echo htmlspecialchars($comment['comment'],ENT_QUOTES,'UTF-8'); ?></li> <?php endforeach; ?> </ul> <?php if ($page > 1) : ?> <a href="?page=<?php echo $page-1; ?>">前</a> <?php endif; ?> <?php for ($i = 1; $i <= $totalPages; $i++) : ?> <?php if ($page == $i) : ?> <strong><a href="?page=<?php echo $i; ?>"><?php echo $i; ?></a></strong> <?php else: ?> <a href="?page=<?php echo $i; ?>"><?php echo $i; ?></a> <?php endif; ?> <?php endfor; ?> <?php if ($page < $totalPages) : ?> <a href="?page=<?php echo $page+1; ?>">次</a> <?php endif; ?> </body> </html>

    • ベストアンサー
    • PHP
  • myaql php ページャー total

    検索機能プラスページャー機能を作っているのですが$totalが取れません。 echo $total;にしても数字が出てきません。 検索機能をつけずに元あるデータからはうまくいきました。 ご教授お願いいたします。 ソースは下記です <?php $cityid=$_POST['city']; $brandid=$_POST['brand']; $syasyu=$_POST['ysasyu_sentaku']; $page = 1; $limit = 2; $offset = $limit * ($page - 1); $dsn='mysql:dbname=****host=mysql1.**** $user=***; $password=***** $dbh=new PDO($dsn,$user,$password); $dbh->query('SET NAMES utf8'); if($brandid=='') { $sql='SELECT COUNT (*)FROM zyoho WHERE cityid=? OR brandid=?'; }else{ $sql='SELECT COUNT (*) FROM zyoho WHERE cityid=? AND brandid=?'; } $stmt=$dbh->prepare($sql); $data[]=$cityid; $data[]=$brandid; $stmt->execute($data); $db=null; $total=$stmt->fetchColumn(); $lastpage= ceil($total/$limit); if($brandid=='') { $sql='SELECT naiyo FROM zyoho WHERE cityid=? OR brandid=? LIMIT '.$limit.' OFFSET '.$offset; }else{ $sql='SELECT naiyo FROM zyoho WHERE cityid=? AND brandid=? LIMIT '.$limit.' OFFSET '.$offset; } $stmt = $dbh->prepare($sql); var_dump($data); $stmt->execute($data); $db = null; while($row = $stmt->fetch(PDO::FETCH_ASSOC)){ echo $row['naiyo']; echo'</br>'; } echo '<ul class="pager">'; ?> <?php if($page > 1){?> <li><a href="pager.php?page=<?php echo $page-1; ?>"> << </a></li> <?php }。 for($i = $page; $page-2 < $i && $i <= $page+4 && $i <= $lastpage; $i++){ ?> <?php if($i == $page){ ?> <li><a href="kensaku_pager.php?page=<?php echo $i; ?>"><?php echo '<font color="#FF4DC4">'.$i.'</font></a></li>'; }else{?> <li><a href="pager.php?page=<?php echo $i; ?>"><?php echo $i.'</a>'; ?> <?php echo '</li>'; } }。 if($page < $lastpage){ ?> <li><a href="pager.php?page=<?php echo $page+1; ?>"> >> </a></li> <?php } ?> </ul>

    • ベストアンサー
    • MySQL
  • functionsでどこまで括るのが正解なのか

    RSSを取得→格納→表示→定期的にキャッシュをphpで行っております。 index.phpにすべて記載したところfunctions.phpを利用したほうが良い、require_onceでpage.phpなどからindex.phpに読み込むようご指摘をいただいたので、コードを考えてみたのですがどの範囲までfunctionで括るのが正解なのかわかりません。 意見がわかれておりまして、役割によって分けるべきという方と、page.phpのみfunctions.phpを使いそのほかはrequire_onceで読み込めばいいという方と、すべてrequire_onceで読み込めばいいという方の3パターンありました。 どの方法が1番適切でしょうか?コードは以下になります。 <?php //別ファイルにして読み込む場合 function db($hlxclitx_wp1){//DB名を引数として受け取る $dbname //DB接続 try { $pdo = new PDO(“mysql:dbname=”$hlxclitx_wp1”_name;host=”localhost”;charset=utf8″,”hlxclitx_wp1”,”E.HrypHWxNmltXgC5eS26”)); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $pdo; }catch (PDOException $e) { echo $e->getMessage(); return $db = null; } } // カテゴリーIDをキーにしたカテゴリー配列を生成 function get_category_name_by_id($categories) { foreach (get_categories() as $category) { $categories[$category->cat_ID] = $category; } // 投稿の情報を追加 function set_other_data($post) { // アイキャッチIDを取得 $post_thumbnail_id = get_post_thumbnail_id($post); // アイキャッチ画像の確認 if ($post_thumbnail_id) { // 存在する $image_src = wp_get_attachment_image_src($post_thumbnail_id); // サムネイルの画像URLを設定 $post->thumbnail = $image_src[0]; } else { // 存在しない $post->thumbnail = 'noimage.jpg'; } // カテゴリーIDを取得 $post->categories = wp_get_post_categories($post->ID); // コメントテキスト if (0 == $post->comment_count) { // コメントなし $post->comments = __('No Comments'); } else { // コメントあり $post->comments = $post->comment_count.'件のコメント'; } // コメントリンク $post->comments_link = get_comments_link($post->ID); } //古いデータを削除 //※先に実行する //ものがないものはfunctons.phpに書いても使えないので、require_onceでまとめて読み込む認識 function delete_date_pdo($delete_date) { $sql = 'DELETE FROM rss_feed WHERE date < ?'; $stmt = $dbh->prepare($sql); $delete_date = date('Y-m-d H:i:s', strtotime('-1 week')); //※削除対象日付 $stmt->execute([$delete_date]); } //RSS保存 function save_url_rss($stmt){//本来は値がほしいところでfunction{}するのだろう長さの加減がわからず $url1 = [ 'http://nns2ch.net/index.rdf', 'http://aqua2ch.net/index.rdf', 'https://worldfn.net/index.rdf', ]; $stmt = $dbh->prepare('insert into rss_feed (title, link, date, img) values (?, ?, ?, ?) on duplicate key update title=?, link=?, date=?, img=?'); foreach ($url1 as $url) { if (($rss = @simplexml_load_file($url)) === false) { continue; } foreach ($rss->item as $item) { $dc = $item->children('dc', true); $date = date('Y-m-d H:i:s', strtotime($dc->date)); //※削除対象日付より古いRSSは保存しない if ($date < $delete_date) { continue; } $title = $item->title; $link = $item->link; $content = $item->children('content', true); $result = preg_match('/<img[^>]*src=\"([^"]+)\"[^>]*>/i', $content->encoded, $matches); if (1 == $result) { $img = $matches[1]; } else { $img = ''; } $stmt->execute([$title, $link, $date, $img, $title, $link, $date, $img]); } } } function one_page_count($post_items){ //表示設定 $current_page = $_REQUEST['page'] ?? 1; //現在ページ $block_per_page = 2; //ページあたりブロック件数 $rss_per_block = 18; //ブロックあたりRSS件数 $posts_per_block = 5; //ブロックあたり投稿件数 //RSS読み込み $rss_per_page = $block_per_page * $rss_per_block; //ページあたりRSS件数 $rss_offset = ($current_page - 1) * $rss_per_page; //RSSオフセット $sql = 'SELECT * FROM rss_feed ORDER BY date DESC LIMIT ?,?'; $stmt = $dbh->prepare($sql); $stmt->bindParam(1, $rss_offset, PDO::PARAM_INT); $stmt->bindParam(2, $rss_per_page, PDO::PARAM_INT); $stmt->execute(); $rss_items = $stmt->fetchAll(PDO::FETCH_OBJ); //投稿読み込み $posts_per_page = $block_per_page * $posts_per_block; //ページあたり投稿件数 $posts_offset = ($current_page - 1) * $posts_per_page; //投稿オフセット $args = [ 'posts_per_page' => $posts_per_page, 'offset' => $posts_offset, ]; $post_items = get_posts($args); } ?>

    • ベストアンサー
    • PHP
  • PDOのprepareでLIKEの部分一致が使えません・・

    http://d.hatena.ne.jp/Sybian/20070521/p1 のサイトの例のように、LIKE '%文字列%' をprepareしようとしたのですが上手く結果が返りません。 PDOのプリペアステートメントは、 LIKEの部分一致や先頭一致に非対応なのでしょうか? $query="SELECT * FROM table WHERE id=:id OR like name='%:name%'"; $pdo=new PDO('mysql:host=localhost;dbname=database','user','password'); $stmt=$pdo->prepare($query); $stmt->bindValue(':id',$id,PDO::PARAM_INT); $stmt->bindValue(':name',$name,PDO::PARAM_STR); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC);

    • ベストアンサー
    • PHP
  • このページ切り替えであっていますか?

    サンプルスクリプトの部分を使ってページナビをつけたのですが、 正常に動作しません。"1"としか表示されません。 // オフセットに値がなければ0をセット if(!$input_offset) { $input_offset = 0; } <省略> $query = "SELECT * FROM hoge LIMIT 10 OFFSET {$input_offset}"; <省略> // ナビゲーター $query = "SELECT count(*) FROM hoge"; $result = @mysql_query($query, $db); $data_size = @mysql_result($result, 0, 0); if($data_size > 0) { $last_page = ceil($data_size / LB_DATA_LIMIT); print <<<_EOT_ <table border="0" cellspacing="0" cellpadding="5" width="500"> <tr> <td>\n page&nbsp; _EOT_; for ($i = 1; $i <= $last_page; $i++) { $offset = ($i - 1) * 5; printf('<a href="index.php?mode=395&offset=%d">%d</a>', $offset, $i); //←ここでページ数、ナビつける print "&nbsp;&nbsp;"; } } 上記コードでちゃんと「1.2.3.4.・・・」というナビはつくでしょうか? どこか間違いがあれば教えてください。 よろしくお願いします。

    • ベストアンサー
    • PHP

専門家に質問してみよう