我已经写了一份申请律师事务所的申请书。有一个API来获取有关法庭案件的信息。当用户进入特定案例时,我已经实现了对前端的API调用;在法庭上,一个选项卡中充满了来自这个API的关于这个案件的状态的信息。
这段代码是从每天的cron作业中运行的;对于我的应用程序中的所有情况,它检查last updated filed并将其与我的DB中上次保存的last updated filed匹配。如果它们不匹配,那么我的应用程序中的通知系统就会通知被分配的人在这种情况下的更改。
因此,简而言之:我的应用程序和电子邮件中所有法庭案件的变化都会自动通知系统。
我对curl和PHP调用有点陌生,通常使用JS,所以请容忍我。
我对这个脚本有一些性能问题。DB调用和循环只有70次左右。而且有点慢。我担心它是否会在更大的数字下起作用。
附带注意: API没有一次获取所有数据的选项。我得把它循环起来:
function eSudovi()中进行,数据保存在$eSudovi中。function findSudCode($val, $eSudovi)来过滤数据,并在循环中从中获取一些信息。with function ePredmeti($sud, $pred)进行$epredmet = ePredmeti($sudCode, $sudBroj);。因为我刚开始使用PHP,所以我正在寻找关于改进这一点的建议。有人告诉我,每次打开和关闭连接都可以做些什么?
我已经按照在API调用循环中尝试访问空& isset类型值的数组偏移量中的建议实现了时间检查。看上去时间到处都是,没有连接到响应的类型。
我正在使用PHP7.4版本。
// ONE API CURL CALL AT START
function eSudovi()
{
$endpoint = "xxx";
$qry = '{"query":"query{sudovi {id, sudNaziv}}"}';
$headers = array();
$headers[] = 'Content-Type: application/json';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $qry);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result, true);
}
// SAVE DATA FOR LATER USE
$eSudovi = eSudovi()["data"]["sudovi"];
//FILTER THAT DATA FROM LATER LOOP
function findSudCode($val, $eSudovi)
{
foreach ($eSudovi as $key => $value) {
if ($value["sudNaziv"] == $val) {
return $value["id"];
}
}
}
// 2nd API CURL CALL THAT IS USED IN LATER LOOP
function ePredmeti($sud, $pred)
{
$endpoint = "xxx";
$qry = '{"query":"query{ prvi:predmet(sud: ' . $sud . ', oznakaBroj: \"' . $pred . '\") {lastUpdateTime}}"}';
$headers = array();
$headers[] = 'Content-Type: application/json';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $qry);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result, true);
}
// DB GET DATA
$results = mysqli_query($con, "
SELECT DISTINCT predf_nas_br, predf_odv, predf_SUD, predf_SUDBROJ
FROM PREDMETIFView
WHERE predf_SUD <> '' AND predf_SUDBROJ <> '' AND predf_SUDBROJ NOT LIKE '% %'
UNION ALL
SELECT DISTINCT predp_nas_br, predp_odv, predp_SUD, predp_SUDBROJ
FROM PREDMETIPView
WHERE predp_SUD <> '' AND predp_SUDBROJ <> '' AND predp_SUDBROJ NOT LIKE '% %'
;");
while ($row = $results->fetch_assoc()) {
// LOOP THAT BD DATA
foreach ($row as $key => $value) {
if ($key == "predf_nas_br") {
$nas = $value;
}
if ($key == "predf_SUD") {
$sud = trim($value);
if (!empty($sud) && isset($sud)) {
$sudCode = findSudCode($sud, $eSudovi);
}
};
if ($key == "predf_SUDBROJ") {
$sudBroj = trim($value);
};
if (!empty($sudCode) && !empty($sudBroj) && isset($sudCode) && isset($sudBroj)) {
// echo $sudCode . "
";
// echo $sudBroj . "
";
$epredmet = ePredmeti($sudCode, $sudBroj);
print_r($epredmet);
echo "
";
if (isset($epredmet["data"]["prvi"]["lastUpdateTime"])) {
$lastUpdateTime = $epredmet["data"]["prvi"]["lastUpdateTime"];
$dateTime = str_replace("T", " ", $lastUpdateTime);
echo $nas . " - " . $dateTime . "
";
}
}
}
};编辑:
我得到的地址是:
Mysql查询52个结果花费了0.0002秒,我不认为这会有什么问题,它只做了一次,我说每个测试DB只有大约70个结果。总之,所有的东西都有正确的索引等等..。
我将用户代理添加到curl中,并使用类实现了堆栈过流解决方案,该类应该解决curl连接的重用问题。
我还创建了代码,这样您就可以使用示例数据和端点测试它:
$arr = [
["Županijski sud u Zagrebu", "13-Kir-t-us-330/20"],
["Općinski građanski sud u Zagrebu", "P-2315/96"],
["Upravni sud u Splitu", "Uslgr-66/2020"],
["Općinski građanski sud u Zagrebu", "P-2282/2018"],
["Općinski građanski sud u Zagrebu", "P-785/2020"],
["Općinski kazneni sud u Zagrebu", "K-1899/2019"],
["Općinski građanski sud u Zagrebu", "P-12107/2019"],
["Županijski sud u Osijeku", "K-Us-9/2019"],
["Županijski sud u Zagrebu", "K-Us-11/2018"],
["Općinski sud u Splitu", "Z-27820/20"],
["Općinski prekršajni sud u Zagrebu", "Pp-226/2020"],
["Općinski prekršajni sud u Zagrebu", "Pp-5211/2021"],
["Općinski prekršajni sud u Zagrebu", "Pp-5142/2021"],
["Upravni sud u Zagrebu", "Usl-348/20"],
["Općinski građanski sud u Zagrebu", "P-2931/2021"],
["Općinski građanski sud u Zagrebu", "Z-36742/2010"],
["Općinski građanski sud u Zagrebu", "Z-20259/2020"],
["Općinski građanski sud u Zagrebu, ZK odjel", "Z-29964/2020"],
["Općinski građanski sud u Zagrebu", "Pn-3651/2017"],
["Općinski radni sud u Zagrebu", "Pr-1676/2015"],
["Općinski građanski sud u Zagrebu", "P-1037/2008"],
["Općinski sud u Kutini", "Pn-160/2019"],
["Trgovački sud u Zagrebu", "Povrv-912/2018"],
["Trgovački sud u Zagrebu", "P-1637/2019"],
["Trgovački sud u Zagrebu", "P-1560/19"],
["Trgovački sud u Zagrebu", "P-1318/2018"],
["Trgovački sud u Zagrebu", "P-1477/2018"],
["Općinski građanski sud u Zagrebu, ZK odjel", "Z-58743/19"],
["Općinski građanski sud u Zagrebu, ZK odjel", "Z-49863/2019"],
["Općinski sud u Sesvetama, ZK odjel", "Z-440/2014"],
["Općinski građanski sud u Zagrebu", "Pn-2545/2018"],
["Općinski sud u Splitu, ZK odjel Supetar", "Z-20786/2019"],
["Općinski građanski sud u Zagrebu, ZK odjel", "Z-34316/2020"],
["Općinski građanski sud u Zagrebu, ZK odjel", "Z-34825/12"],
["Općinski građanski sud u Zagrebu, ZK odjel", "Z-55780/2013"],
["Općinski građanski sud u Zagrebu, ZK odjel", "Z-36302/2016"],
["Općinski građanski sud u Zagrebu", "Ovr-1465/2019"],
["Općinski građanski sud u Zagrebu", "P-766/2019"],
["Općinski građanski sud u Zagrebu", "Ovr-375/2020"],
["Općinski građanski sud u Zagrebu", "R1-555/2020"],
["Trgovački sud u Zagrebu", "R1-4/2021"],
["Općinski sud u Splitu", "P-4300/2020"],
["Općinski građanski sud u Zagrebu", "Z-52429/2019"],
["Općinski sud u Novom Zagrebu", "Z-22493/2019"],
["Općinski sud u Sesvetama", "Z-10836/2019"],
["Općinski sud u Sesvetama", "Z-10833/2019"],
["Općinski radni sud u Zagrebu", "Pr-3823/2021"],
["Općinski radni sud u Zagrebu", "Pr-3326/2021"],
["Općinski građanski sud u Zagrebu", "Z-5768/21"],
["Općinski radni sud u Zagrebu", "Pr-13210/2020"],
["Općinski radni sud u Zagrebu", "Pr-3936/2021-2"],
["Upravni sud u Zagrebu", "Usl-49/18"]
];
function eSudovi()
{
$endpoint = "https://e-predmet.pravosudje.hr/api/";
$qry = '{"query":"query{sudovi {id, sudNaziv}}"}';
$headers = array();
$headers[] = 'Content-Type: application/json';
$ch = curl_init();
$agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)';
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $qry);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result, true);
}
$eSudovi = eSudovi()["data"]["sudovi"];
function findSudCode($val, $eSudovi)
{
foreach ($eSudovi as $key => $value) {
if ($value["sudNaziv"] == $val) {
return $value["id"];
}
}
}
class ePredmeti
{
public $epredmet;
private $curl, $ini_opt;
function __construct()
{
$endpoint = 'https://e-predmet.pravosudje.hr/api/';
$headers = ['Content-Type: application/json'];
$timeout = 30;
$agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)';
$this->curl = curl_init();
$this->ini_opt = [
CURLOPT_USERAGENT => $agent,
CURLOPT_URL => $endpoint,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_CONNECTTIMEOUT => $timeout,
CURLOPT_TIMEOUT => $timeout
];
}
public function _exec($sud, $pred)
{
$start = microtime(true);
$query_opt = [
CURLOPT_POSTFIELDS =>
'{"query":"query{ prvi:predmet(sud: ' . $sud . ', oznakaBroj: \"' . $pred . '\") {lastUpdateTime}}"}'
];
curl_reset($this->curl);
curl_setopt_array($this->curl, $this->ini_opt);
curl_setopt_array($this->curl, $query_opt);
$ret = curl_exec($this->curl);
if (!curl_errno($this->curl)) {
if (curl_getinfo($this->curl, CURLINFO_HTTP_CODE) !== 200) {
echo 'HTTP error: ' . $http_code . '
';
$this->epredmet = null;
} else {
$this->epredmet = json_decode($ret, true);
}
} else {
echo curl_error($this->curl) . '
';
$this->epredmet = null;
}
echo 'Took: ' . (microtime(true) - $start) . '
';
}
}
$mycurl = new ePredmeti();
foreach ($arr as $value) {
$sudCode = findSudCode(trim($value[0]), $eSudovi);
$sudBroj = trim($value[1]);
if (!empty($sudCode) && !empty($sudBroj) && isset($sudCode) && isset($sudBroj)) {
// echo $sudCode . "
";
// echo $sudBroj . "
";
$mycurl->_exec($sudCode, $sudBroj);
// var_dump($mycurl->epredmet);
// echo "
";
if (isset($mycurl->epredmet["data"]["prvi"]) && !empty($mycurl->epredmet["data"]["prvi"])) {
if (isset($mycurl->epredmet["data"]["prvi"]["lastUpdateTime"]) && !empty($mycurl->epredmet["data"]["prvi"]["lastUpdateTime"])) {
$lastUpdateTime = $mycurl->epredmet["data"]["prvi"]["lastUpdateTime"];
$dateTime = str_replace("T", " ", $lastUpdateTime);
echo $dateTime . "
";
}
}
}
}由于某种原因,这个测试脚本的速度要快一些,但是仍然会有0.01到5,6,有时是7秒的变化。在生产中,我仍然有504网关超时在一个DB上。
我害怕在很多记录上这样做.
欢迎任何其他建议。
编辑:
我注意到,这个GraphQL APi在一个请求中确实支持多个情况,它只需要前面的别名。所以我的问题解决了..。
发布于 2021-06-29 19:18:12
提示:重用卷发句柄可以保持与服务器的连接打开。因为您是在同一个主机上标记重复请求,这应该会加快速度。在代码开始时使用$ch = curl_init();,退出ePredmeti函数,以便重用curl实例。
但你并不是说代码的哪一部分是慢的。我们不能测试它,否则您应该提供一个公共URL。我建议您在代码和函数中添加几个打印,以显示时间戳,然后查看瓶颈所在。
可以简单到:
echo(date('d/m/Y H:i:s', time()));然后,您可以确定哪一部分需要优化。
数据库查询本身也可能需要很长时间,因为它没有经过优化,而且很可能没有利用表索引(如果它们甚至存在的话)。您应该单独度量该查询的平均时间,并使用查询计划(在Mysql中使用explain命令),如果您发现运行该查询确实需要很长时间,则应该尝试使该查询更好地执行。这主要取决于你是否有很多记录在你的桌子或一个适度的数字。
这也是有可能的网站应用某种形式的速率限制和减慢你。您应该将user代理欺骗到主流浏览器(使用CURLOPT_USERAGENT),因为在网站上很明显,您的脚本是一个机器人。他们可以决定惩罚你并控制交通。
https://codereview.stackexchange.com/questions/263586
复制相似问题