EDIT xdebug 및 netbeans를 사용하여 디버깅을 시도했습니다. 일부 중단 점을 넣으면 디버그 세션 중에 내보내기가 작동한다는 것은 이상한 일입니다. 그러나 브레이크 포인트가 없으면보다 현실적인 환경에서 수출이 효과적이지 않습니다.PHP Redis 세션 저장 안함
코드의 일부분에 잠자기를 추가하려고했습니다.
필자는 Redis 커밋이 완료되기 전에 PHP가 끝나고 있다고 생각합니다. 어쩌면 Redis 연결이 비동기 적으로 수행되고 있지만 PRedis를 확인했고 기본값은 동기 연결입니다.
보고 도구를 작성 중입니다.
여기에 기본적인 문제가 있습니다.
보고서를 세션 개체에 저장하지만 나중에 세션 개체에서 보고서를 가져올 때 나중에 요청하면 보고서가 사라집니다.
다음은 더 자세한 버전입니다.
나는 사용자는 어떤 테이블 형태로 보고서를 볼 수 있도록$_SESSION['report_name_unixtimestamp'] = gzcompress(serialize($reportObject));
같은 세션에 '보고서'객체를 저장하고 그들이 원하는 경우 그들은 그것을 내보낼 수 있습니다. 보고서가 바뀔 수 있으므로 세션에 저장하는 아이디어는 사용자가 PDF, Excel 등으로 내보낼 때보고있는 것과 동일한 보고서를 가져 오는 것입니다.
사용자가 내보내기 버튼을 클릭하면 PHP 쪽에서 세션으로 이동하고 get 매개 변수로 제공된 키를 통해 보고서를 가져 와서 압축을 풀고 직렬화 해제 한 다음 내보내기를 생성하여 사용자에게 보냅니다. 다운로드.
더 나은 세션 관리를위한 도구로 Redis 캐싱 서버를 도입 할 때까지이 점이 잘 작동했습니다. 지금은 어떻게됩니까
은 다음
우리는 보고서가 캐시에 저장 얻을 것이다 및 내보내기가 성공적으로 작동을 처음 실행.
동일한 세션에서 동일한 사용자 계정으로 보고서를 다시 실행합니다. unixtimestamp가 변경되므로 $_SESSION
에 두 개의 항목이 있어야합니다. ($_SESSION['report_name_oldertimetamp']
및 $_SESSION['report_name_newertimestamp']
). 내보내기 버튼을 다시 클릭하면 파일이 존재하지 않는다는 오류가 발생합니다 (서버에서 보내지 않았기 때문에).
새 버전의 보고서에 대해 redis 서버를 확인하면 해당 보고서는 존재하지 않지만 이전 타임 스탬프는 그대로 유지됩니다.
이제는 파일 세션 관리에서 작동하지만 Redis에서는 작동하지 않습니다. 우리는 PHP뿐만 아니라 순수 PHP 클라이언트 Predis에 대한 redis 모듈을 시도했습니다.
누구에게 아이디어가 있습니까?
- 레디 스 메모리가 부족하지 않은 : 여기 은 몇 가지 더 자세한 내용입니다. 우리는 이것을 여러 번 확인했습니다.
- 세션에서 보고서 개체의 serialize를 해제하려면 보고서 클래스가 이미 포함되어 있어야한다는 것을 이미 알고 있습니다. (기억, 첫 번째 내보내기 잘 작동하지만 그 이후의 모든 실패)
- 보고서가 실행되는 요청 중에 php 세션 개체를 확인하면 최신 보고서가 포함되지만 결코 Redis가 만들어지지 않습니다.
아래는 Predis와 함께 사용되는 세이브 핸들러입니다. redis_session_init는 session_start() 전에 바로 호출하여 등록되도록하는 함수입니다. redis_session_write 함수가 어떻게 작동하는지 모르겠지만 누군가가 저를 도울 수 있습니다.
<?php
namespace RedisSession
{
$redisTargetPrefix = "PHPREDIS_SESSION:";
$unpackItems = array();
$redisServer = "tcp://cache.emcweb.com";
function redis_session_init($unpack = null, $server = null, $prefix = null)
{
global $unpackItems, $redisServer, $redisTargetPrefix;
if($unpack !== null)
{
$unpackItems = $unpack;
}
if($server !== null)
{
$redisServer = $server;
}
if($prefix !== null)
{
$redisTargetPrefix = $prefix;
}
session_set_save_handler('RedisSession\redis_session_open', 'RedisSession\redis_session_close', 'RedisSession\redis_session_read', 'RedisSession\redis_session_write', 'RedisSession\redis_session_destroy', 'RedisSession\redis_session_gc');
}
function redis_session_read($id)
{
global $redisServer, $redisTargetPrefix;
$redisConnection = new \Predis\Client($redisServer);
return base64_decode($redisConnection->get($redisTargetPrefix . $id));
}
function redis_session_write($id, $data)
{
global $unpackItems, $redisServer, $redisTargetPrefix;
$redisConnection = new \Predis\Client($redisServer);
$ttl = ini_get("session.gc_maxlifetime");
$redisConnection->pipeline(function ($r) use (&$id, &$data, &$redisTargetPrefix, &$ttl, &$unpackItems)
{
$r->setex($redisTargetPrefix . $id, $ttl, base64_encode($data));
foreach($unpackItems as $item)
{
$keyname = $redisTargetPrefix . $id . ":" . $item;
if(isset($_SESSION[ $item ]))
{
$r->setex($keyname, $ttl, $_SESSION[ $item ]);
}
else
{
$r->del($keyname);
}
}
});
}
function redis_session_destroy($id)
{
global $redisServer, $redisTargetPrefix;
$redisConnection = new \Predis\Client($redisServer);
$redisConnection->del($redisTargetPrefix . $id);
$unpacked = $redisConnection->keys($redisTargetPrefix . $id . ":*");
foreach($unpacked as $unp)
{
$redisConnection->del($unp);
}
}
// These functions are all noops for various reasons... opening has no practical meaning in
// terms of non-shared Redis connections, the same for closing. Garbage collection is handled by
// Redis anyway.
function redis_session_open($path, $name)
{
}
function redis_session_close()
{
}
function redis_session_gc($age)
{
}
}
진단을 위해서만 세션 변수에 다른 키를 사용할 수 있습니까? md5 ('report_name_unixtimestamp') 또는 'timestamp-reportname'같은가? 배경 : 나는 열쇠가 잘리는 것처럼 보입니다 –
@EugenRieck,이 뜻은 $ _SESSION [md5 ('report_name_1234')]입니까? 아마도, 그러나 첫 번째 보고서 내보내기가 왜 작동하는지 설명하지는 못할 것입니다. 키 길이는 동일한 시간 소인이라는 동일한 이름이므로 보고서에서 동일합니다. 나는 그것을 시도 할 것이다, 고마워. –
@EugenRieck, 작동하지 않았습니다. 내가 제안한대로 md5 해시를 시도했지만 어느 쪽도 작동하지 않습니다. –