• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:RSSをデータベースに格納できない)

RSSをデータベースに格納できない

このQ&Aのポイント
  • 昨日教えていただいたコードで格納して表示するところまで成功しました。自分の不注意でデータベースネームと違う、新規作成したテーブルに格納していたため起こったエラーでした。申し訳ありません。
  • 再度全体のコードと組み合わせてみたのですがエラーが起こり困っております。Uncaught Error: Call to a member function insert() on null
  • <?php $url1 = [ 'http://blog.livedoor.jp/dqnplus/index.rdf', 'http://alfalfalfa.com/index.rdf', 'http://himasoku.com/index.rdf', ]; foreach ($url1 as $url) { $count = 0; $rss = simplexml_load_file($url); foreach ($rss->item as $item) { if ($count >= 8) { break; } ++$count; $title = (string) $item->title; //「$item->title」だけではうまくいかないのでstringにキャスト $link = (string) $item->link; //以下同じ $thumb = (string) $item->thumb->url; $content = (string) $item->description; $wpdb->insert('rssfeed', ['title' => $title, 'link' => $link, 'thumb' => $thumb, 'content' => $content], ['%s', '%s', '%s', '%s']); } } $results = $wpdb->get_results('SELECT * FROM rssfeed'); foreach ($results as $item) { echo $item->title.'<br>'; } ?> <?php $wpdb->show_errors(); ?>

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

  • ベストアンサー
  • dell_OK
  • ベストアンサー率13% (766/5721)
回答No.70

お礼 2022/02/09 18:47 ・cronを同じサイトで複数実装してもエラーにはならないでしょうか? WordPressのCronを試してみました。 CronスケジュールひとつにCronイベントを複数登録できました。 エラーにはならいようです。

php_learn
質問者

お礼

期間をけてからの質問で申し訳ないのですが、コードを整理中に修正が必要な個所があり原因がわかりません echo "<li class=\"sitedate\">{$item->date}</li>"; で画像やカテゴリーなどは表示できるのでしょうか? 個別に指定して表示する必要があるのでしょうか? 1.投稿に画像やカテゴリーなどが表示されず、タイトルと日付けのみ表示されている 2.RSS画像にURLがついておらず画像のみ表示されている ※該当箇所 if (!empty($item->img)) { echo "<li><img src=\"{$item->img}\" width=\"100\"></li>"; } 3.RSSの画像がない場合ダミー画像を表示させたいが書き方が調べてもわからない

php_learn
質問者

補足

ありがとうございます。 引き続きコードを組んでみます…

その他の回答 (69)

回答No.9

dell_OKさんが、ソースコード等詳細教えていただけると思いますので、それまでの状況の整理として、お伺いさせて頂きたいのですが、 開発環境はどのようになっていますか? サーバ上のWordpressで動作確認を行っているという場合、その手順はどのようにされていますか。 一般的なプログラマは、ローカルでテキストエディタでスクリプトファイル(xxx.phpみたいな名称の単一ファイル)を作成して、サーバにアップロードします。 もし、スクリプトファイルを作成する手順を、Wordpressの「外観」>「テーマエディタ」で行っている場合には、回答そのものに多少のブレが発生すると思います。

php_learn
質問者

お礼

データが格納した段階でエラーになっているので原因をお聞きしたのですが、以下の指摘を受けたので構文を少し書き直しています。simplexml_load_fileは格納の前に入れないと邪魔をするようです。 例外を投げるエラー時に例外を投げるようにしたのに、接続時しか try / catch で拾っていない データベース処理の全てを try{ ... } の入れるべき > printf('<h2>%s</h2>', $site_title); で、$site_titleは未定義ですから、エラーになるはず > foreach ($rss->item as $item) { この時点では、 > foreach ($url1 as $url) { > if (($rss = @simplexml_load_file($url)) === false) { のループの抜けた後なので、$url1の最後、または取得できなかった場合の $rss 意図通りではないのでは

php_learn
質問者

補足

開発環境はどのようになっていますか? サーバ上のWordpressで動作確認を行っているという場合、その手順はどのようにされていますか。 A.現在は「外観」>「テーマエディタ」でindex.phpの編集を行っております。 一般的なプログラマは、ローカルでテキストエディタでスクリプトファイル(xxx.phpみたいな名称の単一ファイル)を作成して、サーバにアップロードします。 A.うまくいかない際はxamppでも試していますが、atomでコードの修正を行いcpanel経由でアップロードすることも可能です。WinSCPを使いファイルをアップロードすることもできますがドキュメントルート外のファイルが表示されるだけであまり変わりはありません。 もし、スクリプトファイルを作成する手順を、Wordpressの「外観」>「テーマエディタ」で行っている場合には、回答そのものに多少のブレが発生すると思います。 A.今回の場合はコードのエラーというよりファイルパスが足らないことが原因だと思っております。 wordpressがレンタルサーバーの仕様ではドキュメントルート外にあるため?内部に設置されている仮想サーバーと違い実行できないのではないでしょうか?

  • dell_OK
  • ベストアンサー率13% (766/5721)
回答No.8

なるほど。 私も同じサイトか似たようなサイトを参考に環境を作りました。 ただ、パスワードは手間が増えるだけなので、ローカルマシンではなしにしています。 「wordpress-ja」と言うのは「wordpress-x.x.x-ja.zip」のことですね。 「ダウンロードが完了したら、ファイルをダブルクリックして解凍を行おう。」とあります。 解凍方法をどうされたかわかりませんが、解凍すると「wordpress」フォルダがあります。 このフォルダをそのまま「C:¥xampp¥htdocs」へコピーする必要があります。 それでフォルダは「C:¥xampp¥htdocs\wordpress」となり、URLは「http://localhost/wordpress/」になります。 解凍後のzipファイルは使用しません。 なのでもしかしたら解凍されてないと言うことですね。 wp-load.phpの内容はこんな感じです。 コメントは削除しています。 ここ呼ばれたファイルからさらに呼ばれるファイルもあるので、wp-load.phpだけでは解決しないと思います。 全ファイルを検索しましたが「wordpress-ja」を読み込むところはありません。 phpでzipファイルを解凍して読み込むようなこともしていないと思います。 ---- <?php if ( ! defined( 'ABSPATH' ) ) { define( 'ABSPATH', __DIR__ . '/' ); } if ( function_exists( 'error_reporting' ) ) { error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR ); } if ( file_exists( ABSPATH . 'wp-config.php' ) ) { require_once ABSPATH . 'wp-config.php'; } elseif ( @file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! @file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) { require_once dirname( ABSPATH ) . '/wp-config.php'; } else { define( 'WPINC', 'wp-includes' ); require_once ABSPATH . WPINC . '/load.php'; wp_fix_server_vars(); require_once ABSPATH . WPINC . '/functions.php'; $path = wp_guess_url() . '/wp-admin/setup-config.php'; if ( false === strpos( $_SERVER['REQUEST_URI'], 'setup-config' ) ) { header( 'Location: ' . $path ); exit; } define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' ); require_once ABSPATH . WPINC . '/version.php'; wp_check_php_mysql_versions(); wp_load_translations_early(); $die = '<p>' . sprintf( __( "There doesn't seem to be a %s file. I need this before we can get started." ), '<code>wp-config.php</code>' ) . '</p>'; $die .= '<p>' . sprintf( __( "Need more help? <a href='%s'>We got it</a>." ), __( 'https://wordpress.org/support/article/editing-wp-config-php/' ) ) . '</p>'; $die .= '<p>' . sprintf( __( "You can create a %s file through a web interface, but this doesn't work for all server setups. The safest way is to manually create the file." ), '<code>wp-config.php</code>' ) . '</p>'; $die .= '<p><a href="' . $path . '" class="button button-large">' . __( 'Create a Configuration File' ) . '</a></p>'; wp_die( $die, __( 'WordPress &rsaquo; Error' ) ); } ---- クラスとリンクを付ける方法については改めて回答したいと思います。

php_learn
質問者

お礼

1度試しにwordpressの中にあるファイルをコピーして読み込むようにしてみます。

php_learn
質問者

補足

「wordpress」フォルダがあります。 このフォルダをそのまま「C:¥xampp¥htdocs」へコピーする必要があります。 それでフォルダは「C:¥xampp¥htdocs\wordpress」となり、URLは「http://localhost/wordpress/」になります。 A.この環境にするために1からサイトを作る必要がありませ。通常のレンタルサーバーではwordpressというフォルダがなくpublic_htmlからルートパスをそのままincloudに送っています。wordpressを通さないの理由がわかりませんが、セキュリティのためだと思われます。ドキュメントルート真下に置くということは外部からのアクセスに弱いと書いてありましたので、普通は深いところに置くはずです。 全ファイルを検索しましたが「wordpress-ja」を読み込むところはありません。 phpでzipファイルを解凍して読み込むようなこともしていないと思います。 A.確認ありがとうございます。原因はwordpressのフォルダにある何らかのファイルを通していないか通していても深いところにあるためエラーが起きているかもしれません。 外部からの干渉に対するセキュリティ対策とwordpressを構築しなおすことは勉強のためにやりたいですが、まずはRSSを意図した形で作るほうを自分としては優先するつもりです。

  • dell_OK
  • ベストアンサー率13% (766/5721)
回答No.7

wordpress\index.phpから始まり次々に読み込まれるもの、と言う質問でしょうか。 でしたら以下のようなファイルがあります。 最初のいくつかだけあげておきます。 wordpress\index.php  wp-blog-header.php wp-blog-header.php  wp-load.php  wp-includes/template-loader.php wp-load.php  wp-config.php  wp-includes/load.php  wp-includes/functions.php  wp-admin/setup-config.php それともwordpressフォルダ配下のファイルと言う事であれば、もっとたくさんになります。 ファイルが23個あります。 フォルダが3個「wp-admin」「wp-content」「wp-includes」あり、それぞれの中にもたくさんあります。 もしかして、zipファイルがあるとしたら、すべてのファイルを展開していないのかなと思ったりしています。 それで、すべての設定からやり直す必要がある、と言うことなのでしょうか。

php_learn
質問者

お礼

やはりindex.phpの前にwordpressのフォルダ等を読み込ませる場合はファイル設計から作り直す必要があるようです。

php_learn
質問者

補足

wp-load.phpの先頭部分だけ教えていただけますでしょうか? https://bazubu.com/xampp-wordpress-23795.html 自分はこちらの方法でwordpressを入れたのですが、wordpress-jaを途中で読み込んでないのでエラーが出ているのではないかと思っております。 こちらのファイルを読み込むようにするなら初めからファイル構造を作り直す必要があり、またセキュリティの問題もあるのでそれであるなら既存のコードを完成させようと考えております。 もう1点pdoを扱うほうでどうしてもわからないことがあるのですが、 // 取得した記事データの表示 if ($count === 1) print('<ul>'); $date = date('Y-m-d H:i:s', strtotime($dc->date));//RSS日付け取得 printf('<li>%s:%s:%s</li>', $title, $link, $date,$thumb);// $title, $link, $date,$thumb を表示 } if ($count) print('</ul>'); } このコードにクラスとリンクを付ける方法がわかりません。教えていただけないでしょうか? htmlで書いてみると、下記のようになります。 <ul class="rss_feed"> <li class="sitetitle"><a href="">title</a></li> <li class="sitelink"></li> <li class="sitedate"></li> <li class="sitethumb"><a href="">thumb</a></li> </ul> ※調べてコードを書いてみましたが構造がわからずぐちゃぐちゃになっております。 ↓ if ($count === 1) print('<ul class=rss_feed>'); $date = date('Y-m-d H:i:s', strtotime($dc->date));//RSS日付け取得 printf('<li>%s class="(%s)">//リンク付きタイトル:%s//リンク <li>%s class="(%s)">//データ <li>%s class="(%s)">//リンク付き画像', '<li>$title class="sitetitle"</li><li>$link class="sitelink"</li><a href='.$title[url].'></a>'//リンク付きタイトル <li>$date class="sitedate"</li>//データ <li>$thumb class="sitethumb"</li><a href='.$thumb[url].'></a>'//リンク付き画像 );// $title, $link, $date,$thumb を表示 } if ($count) print('</ul>'); }

  • dell_OK
  • ベストアンサー率13% (766/5721)
回答No.6

補足 2022/01/17 20:37 テストサーバーではうまくいけていることを知ることができてよかったです。 いつもいきなりレンタルサーバーで試しているのではないかと思ってやきもきしていました。 私はコードを提示されたらコードのおかしな部分を探そうとします。 おそらく他の回答してくださる方々もまずはそうだと思います。 コードに問題があるのか環境に問題があるのか、またはその両方の相性に問題があるのか。 この問題の切り分けは重要で、うまくいっているパターンがあるのでしたら、それを知らせてくれることは大切なことだと思っているので、それを知ることができてよかったです。 とは言え、それは私の気持ちがひとつすっきりしただけです。 「wordpressのzipファイル」がないとのことですが、私の環境にはzipファイルはありません。 なのでテストサーバーのzipファイルをよそへ移動させてもうまくいきそうな気がしています。 これはこれで試してみてください。 ちなみにそのzipファイルの内容はどのようなファイルがあるかわかれば教えてください。 レンタルサーバーの制約がいろいろとありそうなのでそれはいまは触れずにいます。 「load.phpを扱うよりphpから取得」と言うのは、RSSの取得のことでしょうか。 セキュリティのことはわかりませんが、質問者さまがload.phpを危惧されており、また、phpの関数でRSS取得には成功しているようなので、それでいいと思います。 https://okwave.jp/qa/q9948592.html お礼 2022/01/17 19:19 「ループ内にあるのでデータがnullなのか確認できていないのではないのか?」 データがnullだった場合、(string)のキャストで""空文字になるので問題ないと私は思っています。 ただ、PHPのバージョンや設定によってキャスト結果がことなるのかも知れないので断定はできません。 nullが原因かどうかは、nullでない値を強制的に与えれば判明するので、それはそれで試してみてください。 例えば、''で括るだけです。 こんな感じにすると元に戻しやすいです。 ---- $title = '(string) $item->title'; //「$item->title」だけではうまくいかないのでstringにキャスト $link = '(string) $item->link'; //以下同じ $thumb = '(string) $item->thumb->url'; $thumbnail = '/images/dummy_thumbnail.jpg'; // 画像がない場合の代替画像 if ( $thumb ){ $thumbnail = $thumb; } $content = '(string) $item->description';//詳細を取得 ---- これでテーブルに追加できるかどうかを試してみてください。

php_learn
質問者

お礼

データが格納した段階でエラーになっているので原因をお聞きしたのですが、以下の指摘を受けたので構文を少し書き直しています。simplexml_load_fileは格納の前に入れないと邪魔をするようです。 例外を投げるエラー時に例外を投げるようにしたのに、接続時しか try / catch で拾っていない データベース処理の全てを try{ ... } の入れるべき > printf('<h2>%s</h2>', $site_title); で、$site_titleは未定義ですから、エラーになるはず > foreach ($rss->item as $item) { この時点では、 > foreach ($url1 as $url) { > if (($rss = @simplexml_load_file($url)) === false) { のループの抜けた後なので、$url1の最後、または取得できなかった場合の $rss 意図通りではないのでは

php_learn
質問者

補足

「wordpressのzipファイル」がないとのことですが、私の環境にはzipファイルはありません。 C:\xampp\htdocs\wordpress\index.php A.答えが明確ではなかったようです。申し訳ありません。 URLを通す際にwordpressのファイルを途中で読み込んでいると思うのですが、その中身は何でしょうか? もし空であるなら勘違いだと思いますが、wordpressに関するライブラリ等が入ってるのではないでしょうか? このファイルを通す必要がある場合すべての設定からやり直す必要があります。 $title = '(string) $item->title'; //「$item->title」だけではうまくいかないのでstringにキャスト $link = '(string) $item->link'; //以下同じ $thumb = '(string) $item->thumb->url'; $thumbnail = '/images/dummy_thumbnail.jpg'; // 画像がない場合の代替画像 if ( $thumb ){ $thumbnail = $thumb; } $content = '(string) $item->description';//詳細を取得 ※こちらのコードをためさせていただいたのですが、同様のエラーが出ました。勘違いだったようです申し訳ありません。

  • dell_OK
  • ベストアンサー率13% (766/5721)
回答No.5

「NOT NULL」については意図はありません。 phpMyAdminの既定値のままにしていただけですし、こだわりはありませんので、解除していただいて構いません。 それはそれで解除して試してみましょう。 今はあやしいところはなくしてしまった方がいいです。 INSERTの直後にもエラーメッセージを表示してみましょう。 「NOT NULL」の影響でしたら、「WordPress データベースエラー: [Column 'カラム名' cannot be null]」が表示されます。 ---- $wpdb->insert('rssfeed', ['title' => $title, 'link' => $link, 'thumb' => $thumb, 'content' => $content], ['%s', '%s', '%s', '%s']); $wpdb->show_errors(); ---- Uncaught Error: Call to a member function insert() on null このエラーメッセージは($wpdbがnullのため)「nullのメンバー関数inserが呼ばれました」的なメッセージで、「そんな関数はありませんよ」と言う意味だと思います。 なので「wp-load.php」がまだ読めていないか、「wp-load.php」がさらに参照しているファイルが読めていないのだと思います。

php_learn
質問者

お礼

解説いただきありがとうございます。 ファイルを更新できないため明確なエラー箇所が確認できません。 実行中のコンピュータプログラムにエラーが発生した際に、直前に実行していた関数やメソッドなどの履歴を表示することは可能なんですが… Stack trace: #0 wp-content/themes/sample_theme/index.php(277): get_rss_feed() #1 wp-includes/template-loader.php(106): include('/home/hlxclitx/...') #2 wp-blog-header.php(19): require_once('/home/hlxclitx/...') #3 index.php(17): require('/home/hlxclitx/...') #4 {main} thrown

php_learn
質問者

補足

テストサーバーではうまくいきレンタルサーバーではうまくいかないのですが、原因はwordpressのzipファイルがサブディレクトリにないことだと思われます。 独自ドメインを契約して設定を行い、インストールしなおす必要がありそうです。 セキュリティの観点から考えてもload.phpを扱うよりphpから取得したほうがよさそうですがどうでしょうか?

  • dell_OK
  • ベストアンサー率13% (766/5721)
回答No.4

私が思っていたのと違う状況ですね。 では、セキュリティのことがあるにしても、一時的に「wp-load.php」を読み込ませるようにしてみて、データベースに保存できるか試せるでしょうか。

php_learn
質問者

お礼

とりあえずコピーしてテーマ内のディレクトリに設置いたしました。 public_html/wp-content/themes/sample_theme

php_learn
質問者

補足

試してみたのですが、読み込みのエラーが出てきます。 デフォルトで設置されているものを使おうと思ったのですが、require_once( dirname( __FILE__ ) . '/wp-load.php' ); //ファイルの先頭で読み込む ※エラー文 require_once(): Failed opening required 'wp-content/themes/sample_theme/wp-load.php' (include_path='.:/opt/cpanel/ea-php74/root/usr/share/pear') ※画像 https://imgur.com/bryewI4

  • dell_OK
  • ベストアンサー率13% (766/5721)
回答No.3

回答No.2を読んでなんとなくわかりました。 「wp-load.php」を意図的に読ませる必要があるのかどうかを考えてみました。 私のコードは「wp-load.php」を読ませていません。 それは$wpdbのオブジェクトをWordPressに任せて準備してもらっているからです。 テーマフォルダの「index.php」に私のコードを入れてもらったと思いますが、もしかしてブラウザで見る時のURLにこのテーマフォルダやさらに「index.php」まで指定しているのではないでしょうか。 例えば、私のコードの「index.php」はここにあります。 http://localhost/wordpress/wp-content/themes/twentytwentyone/index.php ですが、ブラウザで見る時のURLはこれだけです。 http://localhost/wordpress/ 最初に読み込まれるのはこのファイルです。 C:\xampp\htdocs\wordpress\index.php ここから実行が始まるとその途中で「wp-load.php」を読んで$wpdbを準備してくれますし、その後でテーマフォルダの「index.php」が読まれるので、この段階では$wpdbが使えるようになっています。 試しにURLにテーマフォルダを指定してみました。 http://localhost/wordpress/wp-content/themes/twentytwentyone/ すると質問者さまと同じエラーが発生しました。 なので、もしURLにテーマフォルダを指定しているのでしたら、WordPressの起点で試してみてください。 それでしたら、セキュリティのことも問題なくなるのではないでしょうか。

php_learn
質問者

お礼

wp-load.phpへのファイルパスは通しましたが、同様のエラーが発生しております… Uncaught Error: Call to a member function insert() on null in wp-content/themes/sample_theme/index.php:359 Stack trace: $wpdb->insert('rssfeed', ['title' => $title, 'link' => $link, 'thumb' => $thumb, 'content' => $content], ['%s', '%s', '%s', '%s']); 以前別の方にお聞きしましたが、テーブル定義で全部のカラムがNOT NULLなのはどういう意図でしょうか? 「insertするデータ全部に何らかの文字列がセットされている(空文字列ではない)ことを確認されてないですよね? それなのにテーブル側をNOT NULLにするのはだめですと。 指摘をいただいていたのを忘れておりました。 コードが不足しているようです。

php_learn
質問者

補足

解説いただきありがとうございます。 index.phpのファイルの場所としましては以下のようになっております。 public_html/wp-content/themes/自作テーマ/index.php URLはhttp://www.uygyg.cfbx.jp/となっております。 最初に読み込まれるファイルはデフォルトなので index.phpだと思われます。 もしURLにテーマフォルダを指定しているのでしたら、WordPressの起点で試してみてください。 A.WordPress アドレス (URL)とサイトアドレス (URL)は http://www.uygyg.cfbx.jpとなっているのですが、どこから変更可能でしょうか? ダッシュボード→設定→一般から変更しているのですが

  • t_ohta
  • ベストアンサー率38% (5238/13705)
回答No.2

$wpdb はWordPressで使うDBアクセスのインスタンスですが、このPHPのプログラムはWordPress内で実行しているのですか? WordPress内で実行している場合、$wpdbを使用するには wp_load.php をrequire_once で読み込んでおく必要があるので、ソースの先頭に require_once( dirname(dirname(dirname(dirname( __FILE__ )))) . '/wp-load.php' ); と記述するのが一般的な使用方法です。

php_learn
質問者

補足

wp-load.phpはドキュメントルート内に置くと危険だと言われて躊躇しております セキュリティに関しては全くでして… やはりload.phpを扱う必要があるのでしょうか?

  • _kappe_
  • ベストアンサー率68% (1581/2304)
回答No.1

質問文に書かれている内容で全部ですか? $wpdbが初期化されていないように見えます。