3

非常に大きな を使用して Magento で次のステートメントを実行すると、$skuエラーがスローされることなく実行が終了します。Magento、Apache、または PHP のエラー ログにエラーはありません。

Mage::getModel('catalog/product')->loadByAttribute('sku', $sku);

質問: エラーをキャッチするにはどうすればよいですか?

カスタム エラー ハンドラーを設定しようとしましたが、テスト目的で、各エラー ハンドラー関数が呼び出されるエラー状況をトリガーすることもできました。ただし、前述の Magento コードを大きな$skuで実行すると、エラー処理関数は実行されません。

error_reporting( -1 );
set_error_handler( array( 'Error', 'captureNormal' ) );
set_exception_handler( array( 'Error', 'captureException' ) );
register_shutdown_function( array( 'Error', 'captureShutdown' ) );

完全を期すために、これは$skuI'm に渡しloadByAttribute()ます。(sku は無効ですが、それは問題ではありません)

1- 9685 0102046 | 1- 9685 1212100 | 1- 9685 1212092 | 1- 9685 1212096 | 1- 9685 1102100 | 1- 9685 1102108 | 1- 9685 1102112 | 1- 9685 1- 9685 0102056 | 1- 9685 0102058 | 1- 9685 1212104 | 1- 9685 1212108 | 1- 9685 0212058 | 1- 9685 0104050 | 1- 9685 0212050 | 1- 9685 0212056 | 1- 9685 0212045 | 1- 9685 0212052|1- 9685 0212054|1- 9685 1102104|1- 9685 1102124

この問題についての洞察は大歓迎です!

更新: さらに調査すると、これは実行が終了するコード内の正確なポイントです。foreach が実行されると、Magento が MySQL の世界に入り、データベースからデータのロードを開始すると思います。

\Mage\Catalog\Model\Abstract.php

 public function loadByAttribute($attribute, $value, $additionalAttributes = '*')
    {
        $collection = $this->getResourceCollection()
            ->addAttributeToSelect($additionalAttributes)
            ->addAttributeToFilter($attribute, $value)
            ->setPage(1,1);

        foreach ($collection as $object) { // <--------------- HERE
            return $object;
        }
        return false;
    }

注、ロジックを「修正」するのではなく、これらの種類のエラーを適切にキャッチする方法を見つけることにのみ興味があります。これは、ユーザーに適切なエラー メッセージを表示できるようにするためです。上記の不正な SKU の例は不自然であり、Magento アプリをこれらの誤った SKU で動作させるつもりはありません。

更新: エラーの原因

load()によってトリガーされる呼び出しを追跡したforeachところ、Zend / PHP のバグに要約されます。

\www\lib\Zend\Db\Statement.php への呼び出しと_stripQuoted($sql)次のステートメントを追跡しました: $sql = preg_replace("/$q($qe|\\\\{2}|[^$q])*$q/", '', $sql);(Magento 1.7.0.2 の 204 行目)。

ステートメントpreg_replaceによって生成された SQL を使用して を実行すると、プログラムはそのまま終了します。load()Apache のログにも php のログにもトレースはありません。ログは他のものでいっぱいになるため、機能します。

問題に関するこのバグレポートを見つけました。そこでは、それがセグメンテーション違反であることを示しています。そこから立ち直る方法はないのではないでしょうか(?)。

質問は明示的にエラー状態をキャッチする方法に関するものであり、ここでの多くのアドバイスはデータのサニタイズに関するものであったため、報奨金の明確な「勝者」がいるとは思いません. しかし、Franklin P Strube は、少なくともスタックのより深い部分でチェックを行うことをほのめかしたので、彼はそれを理解しました。

みんな助けてくれてありがとう。segfaults の処理方法に関するアドバイスがあれば、共有してください =)。

4

8 に答える 8

1

スクリプトは、あなたが示しているよりもスタックの奥深くで終了している可能性があると思います。コレクションが「foreach」ループを開始するとき、最初に「load」関数を呼び出す必要があります。これは特に SQL を構築する場所です。

ログMage::log((string)$collection->getSelect());を記録して、SQL クエリに問題があるかどうかを確認できます。

または、フィルタリングする前に SKU をサニタイズできますか? おそらくオブザーバーを使用していますか?

于 2012-10-16T02:07:59.767 に答える
0

php.ini、.htaccess、またはini_setを使用してログパスを設定することを忘れないでください。

.htaccessの例:

php_flag log_errors on
php_value error_log /var/www/PHP_errors.log

MagentoがPDOを使用している場合、通常、PDOは例外モードに設定する必要があります。

これは私がPHP5.2.xに使用しているものです。

error_reporting(-1);
ini_set("display_errors", "On");

function errhandler($nSeverity, $strMessage, $strFilePath, $nLineNumber){
    error_log(PHP_EOL.date("Y-m-d H:m:s", time())." ".$strFilePath."#".$nLineNumber.": ".$strMessage.PHP_EOL);
    throw new ErrorException($strMessage, /*nExceptionCode*/ 0, $nSeverity, $strFilePath, $nLineNumber);
}
set_error_handler("errhandler", -1);
于 2012-10-28T21:40:02.627 に答える
0

Magento 1.7 の顧客にも同じエラーが発生します。

サイドバー カートの HTML をフィールドに保存する SQL 挿入ステートメントがあり、そのステートメントでその HTML に追加ラッシュを使用しました。

その html に 1 ~ 5 個の製品がある場合、save ステートメントは正常に実行されます。

5 つ以上の製品がある場合、つまり html は長くなりますが、各製品の部分は同じであるため、このエラーでも実行されます。

プログラムは $sql = preg_replace("/$q($qe|\\{2}|[^$q])*$q/", '', $sql); で停止します。エラーは表示されません。

メモリの問題のようです.6つの製品でサイズの制限(現在は7000文字)を超えているため、プロバイダーはphp設定を変更する必要があると思います..

于 2014-10-01T23:35:57.873 に答える
0

独自のエラー ハンドラーを登録する必要はありません。Magento が既にそれを行っています。あなたがする必要があるのは、いくつかのステップです:

  1. index.php の次の行のコメントを外して、エラー報告をオンにします。

    #ini_set('display_errors', 1);
    
  2. ログがオンになっていることを確認します。管理パネルの [システム] -> [構成] -> [開発者] -> [ログ設定] に移動し、[有効] を [はい] に設定します。var/logこれで、Magento ルートから Magentoログを確認できます。

すべての PHP エラーは、php Fatal Error またはログに分類されます。

于 2012-10-15T11:58:08.647 に答える
0

最初の 2 つの質問:

  • 実際にエラーがあることをどのように知ることができますか? たとえば、php コードのexit一部では、エラーは発生しませんが、スクリプトは終了します。
  • あなたが言う"I guess Magento goes into MySQL world and starts loading up data from the database"。MySQL サーバーで何が起こるか確認しましたか? SQL クエリは本当に送信されますか? 送信された場合、処理、エラー、または停止されていますか?

行から始めて、デバッガーを使用して PHP コードをステップ実行することをお勧めしますforeach ( $collection。使用しているエディター/IDE がわかりません。NetbeansXDebugをセットアップして、ブレークポイントの設定とコードのステップ実行を許可できます。

于 2012-11-02T16:47:18.517 に答える
0

index.php で、次の行を index.php ファイルの先頭に移動します。

ini_set('display_errors', 1);

パーミッションの問題により、あなたの問題がこのトリガーにフラグを立てていないように感じます。これら 2 つのコマンドを実行して、ファイル/ディレクトリにアクセス許可が正しく設定されていることを確認します。

find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
于 2012-10-30T14:23:57.120 に答える
0

foreachスクリプトを殺すのは ではないと思います。

直前に呼び出しを逆アセンブルしてみてください。

public function loadByAttribute($attribute, $value, $additionalAttributes = '*')
{
    $res1 = $this->getResourceCollection();
    $res2 = $res1->addAttributeToSelect($additionalAttributes);
    $res3 = $res2->addAttributeToFilter($attribute, $value);

    $collection = $res3->setPage(1,1);

    foreach ($collection as $object)
        return $object;
    }
    return false;
}

それ以外の場合は、SKU の長さが長すぎる場合、または SKU がサニタイズ チェックに失敗した場合に、単純に例外をスローすることができます。

于 2012-11-02T22:15:07.647 に答える
0

この問題は、PHP がメモリ不足になったときに発生します。

php.ini から許容されるメモリ サイズを増やすか、その場でメモリ制限を増やします。

これを置くini_set('memory_limit', '512M');

于 2012-10-30T12:33:35.157 に答える