无论如何,我都可以缩短此代码并使之更有效。 我有一段时间没有在PHP中搞砸了,有点生锈。
到目前为止-我已经从Google FreeBusy API的外部JS文件中提取了一个数组,然后从WordPress数据库中提取了一个数组以进行比较。
如果数组内的{start-times}彼此不匹配,则从数据库中删除该项目。
我必须制作两个新数组,以使每个数组具有相同的详细信息,而且我不会将google数组与从数据库中提取数组时得到的无关项目进行比较。
我不确定拥有多个foreach循环是否是正确的方法,如果有PHP专家可以给我一些提高效率的技巧,将不胜感激。
<?php
$apiArray = json_decode($myArray, true); //decode the json into a php array
$notCal = $wpdb->get_results("SELECT * FROM `wp_amelia_appointments` WHERE
`internalNotes` = 'freeBusy' AND `serviceId` = 4", ARRAY_A);
foreach ($notCal as $row) {
$databaseArray[] = $row['bookingStart'];
}
foreach ($apiArray as $rows) {
$formattedItem = $rows['start'];
$formattedItem = date('Y-m-d H:i:s', strtotime( "$formattedItem - 10 hours"));
$googleArray[] = $formattedItem;
}
$result = array_diff($databaseArray, $googleArray);
foreach ($result as $itemtoremove) {
$sql = $wpdb->delete('wp_amelia_appointments', array ('bookingStart' => $itemtoremove));
}
答案 0 :(得分:1)
我有一些建议:
可能可以简化获取$databaseArray
的过程。您可以执行SELECT * FROM
而不是SELECT booking_start FROM
,然后使用$wpdb->get_col
(https://codex.wordpress.org/Class_Reference/wpdb#SELECT_a_Column)。
纯粹的风格,但是您可以稍微简化第二个循环:
foreach ($apiArray as $rows) {
$googleArray[] = date('Y-m-d H:i:s', strtotime("{$rows['start']} - 10 hours"));
}
最后,如果要减少数据库交互的次数,可以用带有WHERE booking_start IN
子句的单个删除来替换最终循环。
答案 1 :(得分:1)
如果要从每个嵌套数组foreach
中提取单个键,则可以消除其中的there's a function for that
个循环,
代替:
foreach ($notCal as $row) { //adding only the start times from the database
// to an array called databaseArray
$databaseArray[] = $row['bookingStart'];
}
DO
$databaseArray = array_column($notCal, 'bookingStart');
array_column —从输入数组中的单个列返回值 http://php.net/manual/en/function.array-column.php
如果愿意,您甚至可以执行此操作
$result = array_diff(array_column($notCal, 'bookingStart'), $googleArray);
如果我有来自$ apiArray的数据,我可能可以将$googleArray
替换为array_walk
或array_map
,但可惜我现在懒得这么难。
好吧我撒谎:
$result = array_diff(array_column($notCal, 'bookingStart'), array_map(function(&$item){
return date('Y-m-d H:i:s', strtotime("{$item} - 10 hours"));
}, array_column($apiArray, 'start')));
现在您可以删除所有这些
foreach ($notCal as $row) { //adding only the start times from the database
// to an array called databaseArray
$databaseArray[] = $row['bookingStart'];
}
foreach ($apiArray as $rows) { //adding only the start times from google
// into an array
$formattedItem = $rows['start'];
$formattedItem = date('Y-m-d H:i:s', strtotime( "$formattedItem - 10 hours"));
//gotta convert times from google so that it mathces the time format used in the db
$googleArray[] = $formattedItem;
}
$result = array_diff($databaseArray, $googleArray);
请记住,我正在研究有关此数据的外观的有限知识(和测试能力)。
示例(我如何对其进行测试):
$apiArray = [
['start' => date('Y-m-d')]
];
foreach($apiArray as $rows){
$googleArray[] = date('Y-m-d H:i:s', strtotime("{$rows['start']} - 10 hours"));
}
print_r( $googleArray );
//now this doesn't look much smaller then the above, but because it returns
//exactly what we want (given the code I've seen), you can get rid of
//$s and just stuff it in array_diff.
$s = array_map(function($item){
return date('Y-m-d H:i:s', strtotime("{$item} - 10 hours"));
}, array_column($apiArray, 'start'));
print_r( $s );
输出:
//foreach
Array
(
[0] => 2018-08-21 14:00:00
)
//array map
Array
(
[0] => 2018-08-21 14:00:00
)
所以在夏日
<?php
$apiArray = json_decode($myArray, true); //decode the json into a php array
$notCal = $wpdb->get_results("SELECT * FROM `wp_amelia_appointments` WHERE
`internalNotes` = 'freeBusy' AND `serviceId` = 4", ARRAY_A);
$result = array_diff(array_column($notCal, 'bookingStart'), array_map(function($item){
return date('Y-m-d H:i:s', strtotime("{$item} - 10 hours"));
}, array_column($apiArray, 'start')));
foreach ($result as $itemtoremove) {
//for every difference in the array do this
$sql = $wpdb->delete('wp_amelia_appointments', array ('bookingStart' => $itemtoremove));
//delete each row that matches the booking start time
}
您还可以执行以下操作:
您可能可以在整个数组$result
上执行删除操作,不确定如何在我头顶的wordpress中完成删除操作。但是类似DELETE FROM wp_amelia_appointments WHERE bookingStart IN( ... )
。这应该是非常干净的数据,因为其中一部分是通过date()
运行的,而另一部分则来自我认为是date
或datetime
DB字段bookingStart
的数据。这在某种程度上限制了您的攻击面。现在,我并不是说没有正确准备您的查询,我只是说数据在它的攻击向量中(对于SQLInjection)是有限的,但这将消除最后的foreach
循环。
最后一个更改是(您可能不会告诉我,我使用Wordpress的次数不多)您可能/应该能够将第一个查询更改为:
"SELECT `bookingStart` FROM `wp_amelia_appointments` WHERE
`internalNotes` = 'freeBusy' AND `serviceId` = 4"
将*
切换为bookingStart
,然后仅获取该列。我可以告诉您如何在PDO中完成操作,而不是在wordpress上完成操作。但这可以通过只以所需格式选择所需内容来节省对结果集的array_column($notCal, 'bookingStart')
调用。
希望有帮助。
最后我要说的是,短代码并不总是可读的代码。您应该完全理解我为减少这种情况所做的工作。并能够在您的脑海中处理该代码(这是我最主要的工作)。 PHP并不真正在乎您的代码是否更长一些,这里的性能提升可能不值得一提(除了数据库方面),我没有,但是您应该尝试这样做。
这些是我编写代码时的优先事项:
因此,这确实是列表的底部,但是这些并不是相互排斥的。您可以同时执行所有操作。
干杯。