参数都传了,却报错"msg": "Bad Request: area require, but miss"
<?php
namespace App\Api;
use PhalApi\Api as Api;
class User extends Api {
public function getRules() {
return array(
'loginAcct' => array(
'area' => array('name' => 'area', 'require' => true,'min' => 1, 'source' => 'post', 'desc' => '区号'),
'num' => array('name' => 'num', 'require' => true, 'min' => 1, 'source' => 'post', 'desc' => '手机号')
),
);
}
public function loginAcct() {
$area = $this->area;
$num = $this->num;
return array('is_login' => true, 'user_id' => 8);
}
}
post请求:xxx/?service=App.User.LoginAcct 参数:area=86&num=1234
请求结果:
{
"ret": 400,
"data": {
},
"msg": "Bad Request: area require, but miss"
}
另外一个问题: 重写日志类,然后重新注册日志服务,但在代码中,log方法中参数提示仍然显示原始方法的参数 config/di.php
<?php
use PhalApi\Logger;
use App\Common\Logger\InterfaceLogger as InterfaceLogger;
$di = \PhalApi\DI();
// 日记纪录
//$di->logger = new FileLogger(API_ROOT . '/../../mon', Logger::LOG_LEVEL_DEBUG | Logger::LOG_LEVEL_INFO | Logger::LOG_LEVEL_ERROR);
// TODO 重写日志记录
$di->logger = new InterfaceLogger(API_ROOT . '/../../mon/ios_callplus', Logger::LOG_LEVEL_DEBUG | Logger::LOG_LEVEL_INFO | Logger::LOG_LEVEL_ERROR);
重写的log方法:
public function log($uuid = '', $filename = '', $msg = '', $data = '') {}
使用:
\PhalApi\DI()->logger->log('' ,'sms', 'parameters',$array);
使用PHPstorm编辑器, 把鼠标悬停在log方法上,会有下面这个提示: "Method call uses 4 Parameters,but method signature uses 3 Parameters"
好吧, 问题1和issues-59的原因一样,post请求的问题. 请看下第2个问题是不是有问题.
关于问题2: 1、通常如果需要重载函数,函数的签名应该保持一致,否则会导致PHP报警。即继续是三个参数,剩下的参数可以通过类成员变量来传递,该类成员变量可以在构造函数进行初始化 2、上面的IDE提示,要改动底层di代码才可以,不影响实际运行(但依赖前面第1点)
弱弱的问一句, "函数的签名应该保持一致" 不太理解这里的函数签名是什么意思,请不吝赐教.
参考:https://github.com/phalapi/kernal/blob/master/src/Logger.php
函数的名字和形参列表要和下面保持一样:
/**
* 日记纪录
*
* 可根据不同需要,将日记写入不同的媒介
*
* @param string $type 日记类型,如:info/debug/error, etc
* @param string $msg 日记关键描述
* @param string/array $data 场景上下文信息
* @return NULL
*/
abstract public function log($type, $msg, $data);
你说的意思我明白了. 如果我想在重写的log方法里面增加一个可变的变量,构造函数的初始化就不能解决这个问题了. 我想了想唯一可行的办法就是将想要记录的变量信息,与msg组合在一起, 构造日志格式,然后在重写的log方法里面再做特殊处理.
另外一个问题: 我重新了验签服务,对参数进行加密验证,在这个类中用日志记录各个参数以及加密结果. 正常来说,一个请求进来我会在日志中看到参数加密过程的日志,也会看到请求的方法中所记录的日志,但是我无法判断出现的日志是不是属于同一个请求所产生的日志. 我想通过一个UUID标识来把这两个日志关联起来,那么这个UUID我应该在什么地方生成? 达到如下日志效果:
190418022149633817854|LoginAcct|signName|md5
190418022149633817854|LoginAcct|parameters|{"service":"App.User.LoginAcct"}
190418022149633817854为UUID, 我目前的实现方式会在验签服务和接口服务中生成两个不一样的UUID.
ä¸ä¸ä¸ªé®é¢è§£å³åæ³: å¨éåçæ¥å¿ç±»åå§åçæ¶åçæä¸ä¸ªUUIDå³å¯.
æ°é®é¢: http://docs.phalapi.net/#/v2.0/model?id=%e5%a4%8d%e6%9d%82%e6%96%b9%e6%a1%88%ef%bc%9a%e6%94%af%e6%8c%81%e4%bb%bb%e6%84%8f%e5%a4%9a%e4%b8%aa%e6%95%b0%e6%8d%ae%e5%ba%93
ä¸é¢è¿ä¸ªé¾æ¥éé¢:
- ç¬¬ä¸æ¥,æ¯ä¸æ¯åºè¯¥æè¿°ä¸º"å¨./config/di.phpæä»¶ä¸ï¼ä¸ºæ°çæ°æ®åºè¿æ¥æ³¨åæ°çnotormæå¡", di.phpåæäºdb.php?
- ç¬¬äºæ¥,æ¯ä¸æ¯åºè¯¥æè¿°ä¸º"å¨Modelå±ï¼å¨å ·ä½çModelåç±»ä¸ï¼ç»§æ¿ç¬¬åæ¥çåºç±»", ç»§æ¿åæäºç»§ç»?
æä¸å¤ªæ³ä½¿ç¨NotORMçæ°æ®åºæä½,æåªæ³éè¿NotORMå»ºç«æ°æ®åºçPDOè¿æ¥, ç¶åååççsqlè¯å¥,使ç¨è¿ä¸ªè¿æ¥å»æ¥è¯¢,æçå®è·µè¿ç¨: 1.ç»§ç»ä½¿ç¨config/dbs.phpçæ°æ®åºé ç½® 2.App\Common\Database䏿°å»ºDatabase.phpç»§æ¿NotORMDatabase,å¹¶æªå任使¹å¨.
<?php
namespace App\Common\Database;
use PDO;
use PhalApi\Database\NotORMDatabase;
class Database extends NotORMDatabase{
public function createPDOBy($dbCfg) {
$dsn = sprintf('mysql:dbname=%s;host=%s;port=%d',
$dbCfg['name'],
isset($dbCfg['host']) ? $dbCfg['host'] : 'localhost',
isset($dbCfg['port']) ? $dbCfg['port'] : 3306
);
$charset = isset($dbCfg['charset']) ? $dbCfg['charset'] : 'UTF8';
// æ¯æsql server
if (!empty($dbCfg['type']) && strtolower($dbCfg['type']) == 'sqlserver') {
$dsn = sprintf('sqlsrv:Server=%s,%d;Database=%s',
isset($dbCfg['host']) ? $dbCfg['host'] : 'localhost',
isset($dbCfg['port']) ? $dbCfg['port'] : 1433,
$dbCfg['name']
);
}
$pdo = new PDO(
$dsn,
$dbCfg['user'],
$dbCfg['password']
);
$pdo->exec("SET NAMES '{$charset}'");
return $pdo;
}
}
3.config/db.phpæä»¶ä¸ï¼æ³¨åæ°çnotormæå¡
$di->notorm = new \App\Common\Database\Database($di->config->get('dbs'), $di->debug);
4.App\Common\Database䏿°å»ºMyORMModel.php,ç»§æ¿å¹¶éè½½NotORMModel.
<?php
namespace App\Common\Database;
use PhalApi\Model\NotORMModel;
class MyORMModel extends NotORMModel{
public function getORM($id = NULL) {
return \PhalApi\DI()->notorm;
}
}
- Modelç±»éé¢ç»§æ¿MyORMModel
<?php
namespace App\Model;
use App\Common\Database\MyORMModel as MyORMModel;
class Model_User extends MyORMModel{
public function isUserExist($uid) {
$usrsql = "SELECT uid From CR_USERS where uid = ? limit 1;";
return sizeof($this->getORM()->queryAll($usrsql, array($uid)));
}
}
ç»ææ§è¡å°isUserExist()æ¹æ³è¿å°æ¹çæ¶åæ¥äºé:PHP Fatal error: Uncaught Error: Call to undefined method App\Common\Database\Database::queryAll().
该æä¹è§£å³,æ¯queryAll()æ¹æ³æå¨çResult.php没æå¼ç¨å°å? 该æä¹å¼ç¨?
上面的两点,di.php和继承,都已修正,谢谢提醒。
如果你只使用一个数据库(并且是非MySQL的数据库),其实只需要做第2步和第3步就好。
之所以出错,不是引用问题,而是对象用错了。\PhalApi\DI()->notorm是数据库实例,主要用于连接数据库。如果要操作数据库表,例如进行queryAll()操作,则要基于NotORM的实例,需要通过 \PhalApi\DI()->notorm->$table,这样来完成。
简单来说,上面的第4步和第5步不需要,按原来的使用即可。
我这几天会把文档继续更新补充完成,并重新整理下文档,使之更清晰。
我用的是mysql,我不太喜欢使用NotORM的数据库操作,而且还得分表,为表设计表前缀,觉得太费事. 原有项目也没有这些前缀之类的设计, 再使用框架里的NotORM操作就更不方便了. 我只想有一个地方去建立数据库的PDO连接, 然后写原生的sql语句,使用pdo连接去做数据库操作,比如$pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC). 您有没有好的建议呢?
分表可以不用配置,用NotORM可以直接这样写原生sql语句:
$rs = \PhalApi\DI()->notorm->随便一张表名->queryAll($sql, $params)
更多可查看文档:http://docs.phalapi.net/#/v2.0/model
嗯呢,谢谢你的回复. 可是我按照你说的那样去用的时候报了错:
"msg": "Interal Server Error: no such db:i in servers"
config/dbs.php 配置:
<?php
return array(
'servers' => array(
'ios_callplus' => array( //服务器标记
'type' => 'mysql', //数据库类型,暂时只支持:mysql, sqlserver
'host' => 'localhost', //数据库域名
'name' => 'db', //数据库名字
'user' => 'user', //数据库用户名
'password' => passwd', //数据库密码
'port' => 3306, //数据库端口
'charset' => 'UTF8', //数据库字符集
),
),
'tables' => array(
// 通用路由
'__default__' => array(
'prefix' => '',
'key' => '',
'map' => array('db' => 'ios_callplus'),
),
),
);
apache错误:
PHP Warning: Illegal string offset 'db' in vendor/phalapi/kernal/src/Database/NotORMDatabase.php on line 216
看了下NotORMDatabase.php的代码,再结合apache的错误来看像是键值map的值是个空数组,没有'db'这个键. 但实际上我是在dbs.php里面配置了的,然后在源码216行加了日志,发现了奇怪现象:
\PhalApi\DI()->logger->log('info','map',$map);
\PhalApi\DI()->logger->log('info','map',$map['db']);
$dbDefaultKey = $map['db'];
\PhalApi\DI()->logger->log('info','dbDefaultKey',$dbDefaultKey);
日志结果如下:
map|ios_callplus
map|i
dbDefaultKey|i
现象是: $map != $map'db',且$map['db']只取了字符串'ios_callplus'的第一个字符. 我解释不了....求帮忙.
补充: 数据库操作写法, \PhalApi\DI()->notorm->CR_USERS->queryAll(); CR_USERS是我的表名.
原因很简单,格式错了,少了一层数组,应该这样配置:
'tables' => array(
// 通用路由
'__default__' => array(
'prefix' => '',
'key' => '',
'map' => array(
array('db' => 'ios_callplus'),
)
),
),
你可以对比下默认的配置:https://github.com/phalapi/phalapi/blob/master-2x/config/dbs.php 或查看文档说明:http://docs.phalapi.net/#/v2.0/database-connect
千难万阻终于走通了整个流程. 感谢~
需求定制: 我使用了框架的过滤器服务,对请求进行参数验签, 但是有些接口需要加上特定的秘钥进行加密,有的不需要. 这种情况下能不能实现配置?
http://docs.phalapi.net/#/v2.0/filter?id=%e7%99%bd%e5%90%8d%e5%8d%95%e9%85%8d%e7%bd%ae
接口白名单,了解一下?
我看过了这个文档, 可能我没表述清楚: 我的接口都需要进行参数验参, 不能配置在白名单里. 但是有的接口比较特殊, 需要加入特殊的秘钥进行加密, 有的则不需要加入这个秘钥. 我如何实现这种控制呢? 如果可以能不能把我拉进你们的讨论群里面,谢谢. qq: 1174209654
hello?
QQ群在官网上有入口:www.phalapi.net