草庐IT

PHP PDO语句过滤记录

coder 2023-10-11 原文

我正在使用 PHP PDO 通过 JSON 将对象检索到 iOS 应用程序。 有一个包含事件对象的数据库表。它有三个字段来存储日、月和年。数据库的所有者不想在日期字段中存储日期,这意味着我必须处理它。

应用发送带有参数的 URL,如下所示:

http://..hidden domain./myfile.php?dia_inicio=16&dia_final=15&mes_inicio=11&mes_final=12&ano_inicio=2014&ano_final=2015

这意味着我正在寻找从 16Nov2014 到 15Dec2015 的事件。

这是我的 PHP 代码:

 $sql = 'SELECT * FROM tbagenda  WHERE  (dia_evento => :di AND mes_evento = :mi AND ano_evento = :ai) OR (dia_evento <= :df AND mes_evento = :mf AND ano_evento = :af) ';

    // use prepared statements, even if not strictly required is good practice
    $stmt = $dbh->prepare( $sql );
    $stmt->bindParam(':di', $dia_inicio, PDO::PARAM_INT);
    $stmt->bindParam(':df', $dia_final, PDO::PARAM_INT);
    $stmt->bindParam(':mi', $mes_inicio, PDO::PARAM_INT);
    $stmt->bindParam(':mf', $mes_final, PDO::PARAM_INT);
    $stmt->bindParam(':ai', $ano_inicio, PDO::PARAM_INT); 
    $stmt->bindParam(':af', $ano_final, PDO::PARAM_INT);
    // execute the query
    $stmt->execute();

    // fetch the results into an array
    $result = $stmt->fetchAll( PDO::FETCH_ASSOC );

    // convert to json
    $json = json_encode( $result );

    // echo the json string
    echo $json

我应该如何更改声明以使其适用于以下日期:2014 年 11 月 16 日至 2014 年 11 月 28 日(同月)、2014 年 16 月 16 日至 2014 年 12 月 5 日(同年不同月份)和 2014 年 11 月 16 日至 2015 年 5 月 2 日(不同年份)?

稍后添加:

iOS 日志显示发送到 PHP 文件的 URL:

recuperar_eventos_dia.php?dia_inicio=11&dia_final=26&mes_inicio=11&mes_final=11&ano_inicio=2014&ano_final=2014

PHP 部分:

$start = "$ano_inicio-$mes_inicio-$dia_inicio";
$end = "$ano_final-$mes_final-$dia_final";

// In the SQL, concatenate the columns to make a YYYY-MM-DD date string
// and cast it to a MySQL DATE type.
// That makes it possible to use BETWEEN
$sql = 'SELECT 
  *
FROM tbagenda  
WHERE STR_TO_DATE(CONCAT_WS('-', ano_evento, mes_evento, dia_evento), "%Y-%m-%d") 
     BETWEEN :start AND :end';

// Bind and execute the statement with 2 parameters:
$stmt = $dbh->prepare( $sql );
$stmt->bindParam(':start', $start, PDO::PARAM_STR);
$stmt->bindParam(':end', $end, PDO::PARAM_STR);
$stmt->execute();

// fetch, etc...
$result = $stmt->fetchAll( PDO::FETCH_ASSOC );

        // convert to json
        $json = json_encode( $result );

        // echo the json string
        echo $json;

现在是表 tbagenda 的屏幕截图:

最佳答案

我很抱歉你被这个不幸的表结构困住了。

我建议连接表的列以形成可用的日期字符串,并通过 MySQL 的内置函数 STR_TO_DATE() 将它们转换为日期值。 .对查询字符串输入值执行相同的操作,以使用 BETWEEN 运算符进行正确的日期比较。

// Begin by concatenating the input values into single date strings YYYY-MM-DD
$start = "$ano_inicio-$mes_inicio-$dia_inicio";
$end = "$ano_final-$mes_final-$dia_final";

// In the SQL, concatenate the columns to make a YYYY-MM-DD date string
// and cast it to a MySQL DATE type.
// That makes it possible to use BETWEEN
$sql = "SELECT * 
        FROM tbagenda  
        WHERE STR_TO_DATE(CONCAT_WS('-', ano_evento, mes_evento, dia_evento), '%Y-%m-%d') 
          BETWEEN :start AND :end";

// Bind and execute the statement with 2 parameters:
$stmt = $dbh->prepare( $sql );
$stmt->bindParam(':start', $start, PDO::PARAM_STR);
$stmt->bindParam(':end', $end, PDO::PARAM_STR);
$stmt->execute();

// fetch, etc...
$result = $stmt->fetchAll( PDO::FETCH_ASSOC );

字符串操作会影响这个查询的性能。如您所知,如果日期存储为适当的 DATE 会更好,这样 MySQL 就不需要转换它们来进行比较。然后还可以将它们编入索引。

另请注意,我没有包括日期字符串的验证。您可以考虑在执行查询之前检查它们以确保它们是有效日期。

// strtotime() would return false for invalid date strings...
if (strtotime($start) && strtotime($end)) {
  // The dates are valid, and so you can proceed with the query
  $sql = 'SELECT.....';
}

关于PHP PDO语句过滤记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27073542/

有关PHP PDO语句过滤记录的更多相关文章

  1. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  2. ruby-on-rails - Rails 5 Active Record 记录无效错误 - 2

    我有两个Rails模型,即Invoice和Invoice_details。一个Invoice_details属于Invoice,一个Invoice有多个Invoice_details。我无法使用accepts_nested_attributes_forinInvoice通过Invoice模型保存Invoice_details。我收到以下错误:(0.2ms)BEGIN(0.2ms)ROLLBACKCompleted422UnprocessableEntityin25ms(ActiveRecord:4.0ms)ActiveRecord::RecordInvalid(Validationfa

  3. ruby - 如何在 Ruby 中向现有方法定义添加语句 - 2

    我注意到类定义,如果我打开classMyClass,并在不覆盖的情况下添加一些东西我仍然得到了之前定义的原始方法。添加的新语句扩充了现有语句。但是对于方法定义,我仍然想要与类定义相同的行为,但是当我打开defmy_method时似乎,def中的现有语句和end被覆盖了,我需要重写一遍。那么有什么方法可以使方法定义的行为与定义相同,类似于super,但不一定是子类? 最佳答案 我想您正在寻找alias_method:classAalias_method:old_func,:funcdeffuncold_func#similartoca

  4. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  5. ruby-on-rails - 事件记录 : Select max of limit - 2

    我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).

  6. ruby-on-rails - 在 Controller 中干净地处理多个过滤器(参数) - 2

    我有一个名为Post的类,我需要能够适应以下场景:如果用户选择了一个类别,则只显示该类别的帖子如果用户选择了一种类型,则只显示该类型的帖子如果用户选择了一个类别和类型,则只显示该类别中该类型的帖子如果用户没有选择任何内容,则显示所有帖子我想知道我的Controller是否不可避免地会因大量条件语句而显得粗糙...这是我解决此问题的错误方法-有谁知道我如何才能做到这一点?classPostsController 最佳答案 您最好遵循“胖模型,瘦Controller”的惯例,这意味着您应该将这种逻辑放在模型本身中。Post类应该能够报告

  7. ruby - ruby 乘法语句中星号中断语法前的空格 - 2

    在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl

  8. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  9. Ruby 守护进程导致 ActiveRecord 记录器 IOError - 2

    我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame

  10. ruby - 有没有办法从 ruby​​ case 语句中访问表达式? - 2

    我想从then子句中访问c​​ase语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案

随机推荐