/** * get session id * @return string */ public static function getSessId() { if (empty($_COOKIE[self::SessionIdName])) { $_COOKIE[self::SessionIdName] = md5(microtime(true) . \Sooh\Base\Tools::remoteIP()); $cookieDomain = \Sooh\Base\Ini::getInstance()->cookieDomain(); setcookie(self::SessionIdName, $_COOKIE[self::SessionIdName], time() + 315360000, '/', $cookieDomain); } return $_COOKIE[self::SessionIdName]; }
/** * $guidtype 在构造时使用一次 * a 180组服务器,30几年后溢出,(每个请求需要一个进程处理至少1个毫秒,) * b 18组服务器, 300年后溢出, (每个请求需要一个进程处理至少1个毫秒,) * c 18组服务器, 30年后溢出, (每个请求需要一个进程处理至少0.1个毫秒,) * @param string $guidtype * @return \Sooh\Base\Log\Data */ public static function getInstance($guidtype = 'c') { if (self::$_instance == null) { self::$_instance = new Data(); $dt = \Sooh\Base\Time::getInstance(); self::$_instance->ymd = $dt->YmdFull; self::$_instance->hhiiss = $dt->his; self::$_instance->ip = \Sooh\Base\Tools::remoteIP(); self::$_instance->logGuid = self::$_instance->newLogId($guidtype); \Sooh\Base\Ini::registerShutdown(get_called_class() . '::onShutdown', 'logOnShutdown'); } return self::$_instance; }
/** * 锁定一条记录(TODO: 分散设计后,应该没有很多的冲突几率,考虑加个冲突日志并酌情报警) * @param string $msg msg describe the reason * @param int $secExpire default 3year * @return boolean * @throws ErrorException when record is locked already */ public function lock($msg, $secExpire = 94608000) { $dt = \Sooh\Base\Time::getInstance(); if ($this->lock !== null) { error_log('locked already:' . get_called_class() . ' ' . json_encode($this->pkey)); return false; } else { $this->lock = new \Sooh\DB\Base\KVObjV2Lock(); $this->lock->create = $dt->timestamp(); $this->lock->expire = $this->lock->create + $secExpire; $this->lock->msg = $msg; $this->lock->ip = \Sooh\Base\Tools::remoteIP(); $this->lock->lockedByThisProcess = true; $dbDisk = $this->db(); $tbDisk = $this->tbname(); if ($this->cacheWhenVerIDIs) { $dbCache = $this->db(true); $tbCache = $this->tbname(true); } $where = $this->pkey; $where[$this->fieldName_verid] = $this->r[$this->fieldName_verid]; $nextId = \Sooh\DB\Base\SQLDefine::nextCircledInt($this->r[$this->fieldName_verid]); $tmp = $this->lock->toString(); if ($this->cacheWhenVerIDIs == 0) { $ret = $dbDisk->updRecords($tbDisk, array($this->fieldName_verid => $nextId, $this->fieldName_lockmsg => $tmp), $where); $locked = $ret == 1; } elseif ($this->cacheWhenVerIDIs == 1) { $ret = $dbCache->updRecords($tbCache, array($this->fieldName_verid => $nextId, $this->fieldName_lockmsg => $tmp), $where); $locked = $ret == 1; if ($locked) { $dbDisk->updRecords($tbDisk, array($this->fieldName_verid => $nextId, $this->fieldName_lockmsg => $tmp), $where); } } else { $ret = $dbCache->updRecords($tbCache, array($this->fieldName_verid => $nextId, $this->fieldName_lockmsg => $tmp), $where); $locked = $ret == 1; } if ($locked) { $this->r[$this->fieldName_verid] = $nextId; $this->r[$this->fieldName_lockmsg] = $tmp; return true; } else { error_log('locked failed:' . implode("\n", \Sooh\DB\Broker::lastCmd(false))); return false; } } }
/** * * @param string $type [idfa|imei|md5|mac] * @param string $sn * @param string $phone * @param string $userIdentifier * @param string $contractId * @param array $extraData * @return \PrjLib\DataDig\Log\Device */ public static function ensureOne($type, $sn, $phone = null, $userIdentifier = null, $contractId = null, $extraData = null) { $dt = \Sooh\Base\Time::getInstance(); $deviceId = self::guidMaker($type, $sn); $ddd = \Yaf_Dispatcher::getInstance()->getRequest(); error_log("trace device->ensure(" . $ddd->getModuleName() . '/' . $ddd->getControllerName() . '/' . $ddd->getActionName() . ") " . $deviceId . " phone:{$phone} user:{$userIdentifier}"); $sys = parent::getCopy(array('deviceId' => $deviceId)); try { \Sooh\DB\Broker::errorMarkSkip(\Sooh\DB\Error::tableNotExists); $sys->load(); } catch (\ErrorException $e) { if (\Sooh\DB\Broker::errorIs($e, \Sooh\DB\Error::tableNotExists)) { $sys->createTable(); } } $fields = array('ip' => \Sooh\Base\Tools::remoteIP(), 'ymd' => $dt->YmdFull, 'hhiiss' => $dt->his); try { if ($sys->exists() === false) { foreach ($fields as $k => $v) { $sys->setField($k, $v); } $sys->setField('phone', empty($phone) ? '0' : $phone); $sys->setField('userIdentifier', empty($userIdentifier) ? '' : $userIdentifier); $sys->setField('extraData', empty($extraData) ? '' : json_encode($extraData)); $sys->setField('extraRet', ''); $sys->setField('contractId', empty($contractId) ? '0' : $contractId); try { \Sooh\DB\Broker::errorMarkSkip(\Sooh\DB\Error::duplicateKey); $sys->update(); $sys->flgNewCreate = true; return $sys; } catch (\ErrorException $e) { $sys->reload(); if ($sys->exists() === false) { error_log('error create new device log:' . $e->getMessage() . "\n" . $e->getTraceAsString()); return $sys; } } } $oldPhone = $sys->getField('phone', true); $oldUser = $sys->getField('userIdentifier', true); $oldContractId = $sys->getField('contractId', true); if (!empty($phone) && !empty($oldPhone) && $phone != $oldPhone || !empty($oldUser) && !empty($userIdentifier) && $oldUser != $userIdentifier || !empty($oldContractId) && !empty($contractId) && $oldContractId != $contractId) { $extraDataOld = $sys->getField('extraData', true); $extraRetOld = $sys->getField('extraRet', true); $extraRetOld = is_scalar($extraRetOld) === false ? json_encode($extraRetOld) : $extraRetOld; \Sooh\DB\Broker::getInstance(\PrjLib\Tbname::db_rpt)->addRecord(\PrjLib\Tbname::tb_device_log, array('deviceId' => $deviceId, 'dtChange' => $dt->YmdFull . sprintf('%06d', $dt->his), 'phoneOld' => $oldPhone, 'userIdentifierOld' => $oldUser, 'extraDataOld' => is_scalar($extraDataOld) === false ? json_encode($extraDataOld) : $extraDataOld, 'extraRetOld' => $extraRetOld, 'contractIdOld' => $oldContractId, 'phoneNew' => $phone, 'userIdentifierNew' => $userIdentifier, 'extraDataNew' => empty($extraData) ? '' : json_encode($extraData), 'extraRetNew' => $extraRetOld, 'contractIdNew' => empty($contractId) ? '0' : $contractId, 'ipOld' => $sys->getField('ip', true), 'ipNew' => $fields['ip'])); } foreach ($fields as $k => $v) { $sys->setField($k, $v); } if (!empty($extraData)) { $sys->setField('extraData', empty($extraData) ? '' : json_encode($extraData)); } if (!empty($phone)) { $sys->setField('phone', $phone); } if (!empty($userIdentifier)) { $sys->setField('userIdentifier', $userIdentifier); } //$sys->setField('extraRet', ''); if (!empty($contractId)) { $sys->setField('contractId', $contractId); } $sys->update(); //var_log($sys->dump(),'======================log->filled for '.$sys->tbname()); \Sooh\DB\Broker::errorMarkSkip(\Sooh\DB\Error::tableNotExists); } catch (\ErrorException $e) { error_log("error: on ensure-device:" . $e->getMessage() . "\n" . $e->getTraceAsString()); } return $sys; }
protected function onLogin($accountInfo) { $sess = \Sooh\Base\Session\Data::getInstance(); $sess->set('accountId', $accountInfo['accountId']); $sess->set('nickname', $accountInfo['nickname']); $this->_view->assign('account', array('accountId' => $accountInfo['accountId'], 'nickname' => $accountInfo['nickname'])); /** $userOrAccountId = $this->user; $checkinBook = \Lib\Services\CheckinBook::getInstance(); */ $userOrAccountId = $accountInfo['accountId']; $checkinBook = \Lib\Services\CheckinBook::getInstance($this->getRpcDefault('CheckinBook')); $this->_view->assign('checkinBook', $checkinBook->doGetTodayStatus(1, $userOrAccountId)['data']); $this->_view->assign('shopPoints', array('nleft' => 'todo', 'history' => array('todo'))); $user = \Prj\Data\User::getCopy($userOrAccountId); setcookie('nickname', $accountInfo['nickname'], 0, '/', \Sooh\Base\Ini::getInstance()->cookieDomain()); $user->load(); $dt = \Sooh\Base\Time::getInstance(); if ($user->exists() === false) { $user->setField('nickname', $accountInfo['nickname']); $user->setField('contractId', $accountInfo['contractId']); $user->setField('regYmd', $dt->YmdFull); $user->setField('regHHiiss', $dt->his); $user->setField('regClient', self::tmp_clientType); $user->setField('regIP', \Sooh\Base\Tools::remoteIP()); //$user->setField(self::fieldUser, array()); $user->update(); } else { $user->setField('nickname', $accountInfo['nickname']); $user->setField('lastDt', $dt->timestamp()); $user->setField('lastIP', \Sooh\Base\Tools::remoteIP()); $user->update(); } $sess->shutdown(); $this->returnOK(); }
/** * 账号登入, 失败抛出异常(密码错误,账号找不到等等) * @param $loginName * @param $cameFrom * @param $password * @param array $customArgs * @return mixed * @throws \ErrorException * @throws \Sooh\Base\ErrException * @throws array */ public function login($loginName, $cameFrom, $password, $customArgs = ['contractId']) { if ($this->rpc !== null) { return $this->rpc->initArgs(['loginName' => $loginName, 'cameFrom' => $cameFrom, 'password' => $password, 'customArgs' => $customArgs])->send(__FUNCTION__); } else { $objLogin = \Sooh\DB\Cases\AccountAlias::getCopy($loginName, $cameFrom); $objLogin->load(); if ($objLogin->exists()) { $accountId = $objLogin->getField('accountId'); $this->setAccountStorage($accountId); $this->account->load(); if ($this->account->exists()) { $dt = \Sooh\Base\Time::getInstance(); $cmp = md5($password . $this->account->getField('passwdSalt')); $loginFailed = $this->account->getField('loginFailed'); if ($loginFailed) { $cd = new \Sooh\Base\CD($loginFailed, 750, 3600); if ($cd->isRed()) { throw new \Sooh\Base\ErrException(self::errAccountOrPasswordError); } } else { $cd = new \Sooh\Base\CD(0, 750, 3600); } $ymdhForbidden = $this->account->getField('dtForbidden'); if ($ymdhForbidden) { if ($dt->YmdH <= $ymdhForbidden) { throw new \Sooh\Base\ErrException(self::errAccountLock, 404); } } if ($cmp != $this->account->getField('passwd')) { $cd->add(1); $ret = new \Sooh\Base\ErrException(self::errAccountOrPasswordError, 404); } else { $nickname = $this->account->getField('nickname'); $ret = array('accountId' => $this->account->getField('accountId'), 'nickname' => $nickname); if (!empty($customArgs)) { if (is_string($customArgs)) { $customArgs = explode(',', $customArgs); } foreach ($customArgs as $k) { $ret[$k] = $this->account->getField('contractId'); } } } $this->account->setField('lastIP', \Sooh\Base\Tools::remoteIP()); $this->account->setField('lastDt', $dt->timestamp()); $this->account->setField('loginFailed', $cd->toString()); try { $this->account->update(); } catch (\ErrorException $ex) { \Sooh\Base\Log\Data::error("error on update account when login:"******"\n" . \Sooh\DB\Broker::lastCmd() . "\n" . $ex->getTraceAsString()); } if (is_array($ret)) { return $ret; } else { throw $ret; } } else { throw new \Sooh\Base\ErrException(self::errAccountOrPasswordError, 400); } } else { throw new \Sooh\Base\ErrException(self::errAccountOrPasswordError, 400); } } }
/** * 锁定一条记录(TODO: 分散设计后,应该没有很多的冲突几率,考虑加个冲突日志并酌情报警) * @param string $msg msg describe the reason * @param int $secExpire default 3year * @return boolean * @throws ErrorException when record is locked already */ public function lock($msg, $secExpire = 94608000) { $dt = \Sooh\Base\Time::getInstance(); if ('' !== ($lockMsg = $this->isLocked())) { error_log('locked already:' . get_called_class() . ' ' . json_encode($this->pkey)); return false; } else { // $err= new \ErrorException('record lock:'.$this->r[$this->fieldName_verid]); // error_log($err->getMessage()."\n".$err->getTraceAsString()); $tmp = 'expire=' . ($dt->timestamp() + $secExpire) . '&msg=' . $msg . '&ymd=' . $dt->YmdFull . '&ip=' . \Sooh\Base\Tools::remoteIP(); $where = $this->pkey; $where[$this->fieldName_verid] = $this->r[$this->fieldName_verid]; $ret = $this->db()->updRecords($this->tbname(), array($this->fieldName_verid => $this->r[$this->fieldName_verid] + 1, $this->fieldName_lockmsg => $tmp), $where); if ($ret === 1) { $this->r[$this->fieldName_verid]++; $this->r[$this->fieldName_lockmsg] = $tmp; $this->lockedByMe = true; return true; } else { error_log('locked failed'); return false; } } }