4

Session Upload Progress 機能 ( http://php.net/manual/en/session.upload-progress.php ) を Kohana で動作させようとしています。次のコードを使用して、Kohana を使用せずにローカルで動作させることができました。

<?php
    session_start();
    if (isset($_GET['progress']))
    {
        // does key exist
        $key = ini_get("session.upload_progress.prefix") . 'demo';
        if ( !isset( $_SESSION[$key] ) ) exit( "uploading..." );

        // workout percentage
        $upload_progress = $_SESSION[$key];
        $progress = round( ($upload_progress['bytes_processed'] / $upload_progress['content_length']) * 100, 2 );

        exit( "Upload progress: $progress%" );
    }
?>
<!doctype html>
<head>
</head>
<body>
    <section>
        <h1>Upload Form</h1>
        <form action="" method="POST" enctype="multipart/form-data" target="upload-frame">
            <input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="<?php //echo $uid; ?>demo">
            <p>
                <label>File:</label>
                <input type="file" name="file" required="required">
            </p>
            <p><input type="submit" name="submit" value="Upload"></p>
        </form>

        <iframe id="upload-frame" name="upload-frame" width="1280" height="600"></iframe>

        <div id="file_upload_progress"></div>
    </section>

    <script src="jquery-1.7.1.min.js"></script>
    <script>
        $(document).ready(function() {

            var uploading = false;
            $('form').submit(function() {

                uploading = true;
                $('#upload-frame').one('load', function(){
                    uploading = false;
                });

                function update_file_upload_progress() {
                    $.get("?progress", function(data) {
                        $("#file_upload_progress").html(data);
                        if (uploading) {
                            setTimeout( update_file_upload_progress, 500 );
                        }
                    })
                    .error(function(jqXHR, error) { 
                        alert(error); 
                    });
                }

                // first call
                update_file_upload_progress();
            });
      });
    </script>
</body>
</html>

ただし、Kohana でこのコードを使用すると (もちろん、PHP をコントローラーに分離します) $_SESSION、アップロードの進行状況を追跡するための変数は作成されません。

これは、Kohana でのセッションの仕組みに関係していると思います。session_start()既に実行中の Kohana セッションと競合するため、スクリプトの開始時には使用できません。$_SESSIONまたはコンテンツをダンプするとSession::instance()、PHP Upload Progress 機能によって追加される変数がそこにありません。

では、セッション変数を Kohana で動作させるにはどうすればよいでしょうか?

アップデート

その後、この問題を絞り込むために、Kohana のクリーン インストールを作成しました。Kohana でクラスをインスタンス化しないことでSession、上記のコードを使用でき、正常に動作することがわかりました。

ただしSession、Web アプリケーションに必要なクラスがインスタンス化されると、動作が停止し、$_SESSIONアップロードの進行状況を含む変数が作成されなくなります。これは、Kohana がセッション情報を管理する方法のどこかに問題があると私に信じさせます。構成設定で暗号化をオフにしようとしましたが、違いはありませんでした。

ネイティブセッションを使用しています。

4

2 に答える 2

2

セッション Cookie 名は、php config ( ) で設定されたものとまったく同じでなければなりませんsession.name。例:

return array(
    'native' => array(
        'encrypted' => FALSE,
        'name'      => ini_get('session.name'),
    ),
);

PHP のデフォルトのセッション Cookie 名を使用したくない場合は、実行時に値を設定しても問題を回避できません。つまり、これは機能しません。

ini_set('session.name', 'my_kohana_session_name');

.htaccess ファイルに次の値を設定することで、これを回避できます

php_flag session.name "my_kohana_session_name"

このようにして、php.ini をそのままにしておくことができますが、Kohana アプリケーションのカスタム Cookie 名を保持できます。

私のテストでは、ネイティブ セッション ドライバーを使用している場合、セッションの暗号化がアップロードの進行状況情報に影響しないことが証明されました。ネイティブドライバーを使用する場合は暗号化を使用しないため、設定を無視してください。;)

PS。私が提案することの1つは、ajaxリクエストがキャッシュされていないことを確認することです。キャッシュされていて、新しい応答が表示されない場合がかなりありました。

于 2013-02-01T15:27:48.413 に答える
1

私は解決策を見つけました。

私が行ったことは、PHP で生成さ$_SESSIONれた変数を独自の .xml に読み込むコードを分離することControllerです。私の場合、電子メール、Web URL などの検証などの一般的な AJAX チェック用の AJAX コントローラーがあります。カスタム コントローラー (他のコントローラーの拡張元) からセッション情報を継承しないようにextends、デフォルトのコントローラーです。Controller

したがって、私の新しいスタンドアロンControllerは次のようになります。

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Ajax extends Controller {

    public function action_upload_progress()
    {
            // get upload progress key
            $key = (!empty($_POST['key'])) ? $_POST['key'] : FALSE; 

            // start session to get PHP 5.4 generated $_SESSION variables
            session_start();

            // does key exist
            $key = ini_get("session.upload_progress.prefix") . $key;
            if ( !isset( $_SESSION[$key] ) ) {
                exit( "uploading..." );
            }

            // workout percentage
            $upload_progress = $_SESSION[$key];
            $progress = round( ($upload_progress['bytes_processed'] / $upload_progress['content_length']) * 100, 2 );
            exit( "Upload progress: $progress%" );
    }
}

以前と同じコードを実際のフォームに使用し、JavaScript を微調整して、このコントローラー/アクションにアップロードの進行状況データを取得するように要求します。問題が解決しました!

于 2013-01-23T11:35:06.977 に答える