พบค่าตัวเลขที่ไม่ดี


120

ฉันมีแบบฟอร์มที่ผ่านวันที่สองวัน (เริ่มต้นและสิ้นสุด) ไปยังสคริปต์ PHP ที่จะเพิ่มสิ่งเหล่านั้นลงในฐานข้อมูล ฉันมีปัญหาในการตรวจสอบความถูกต้อง ฉันได้รับข้อผิดพลาดต่อไปนี้

พบค่าตัวเลขที่ไม่ดี

นี่คือตอนที่ฉันใช้สิ่งต่อไปนี้

date("d",$_GET['start_date']);

แต่เมื่อฉันใช้ฟังก์ชันstrtotime ()ตามคำแนะนำของหลาย ๆ ไซต์ฉันจะได้รับวันประทับเวลายูนิกซ์ของ 1/1/1970 มีความคิดอย่างไรที่จะหาวันที่ถูกต้องได้


6
คุณต้องโพสต์สิ่งที่$_GET['start_date']มี
JohnP

1
ฉันถือว่าคุณ$_GET['start_date']ไม่ใช่การประทับเวลาซึ่งคาดว่าโดยdateฟังก์ชันเป็นอาร์กิวเมนต์ที่สอง
Nemoden

JohnP ถูกต้อง คำถามนี้ไม่ชัดเจนและต้องการรายละเอียดการแก้ไขข้อบกพร่องเนื่องจากตัวอย่างที่ทำซ้ำได้น้อยที่สุดนั้นไม่สมบูรณ์ ด้วยเหตุนี้หน้านี้จึงเต็มไปด้วยการคาดเดาเกี่ยวกับวิธีแก้ไขปัญหา ความยุ่งเหยิงนี้ไม่สนุกสำหรับนักวิจัย เป็นเรื่องตลกที่คำถามที่น่าสงสารอายุมากสามารถรับ UV ได้มากมายเพียงแค่เรื่องของเวลาและการลงคะแนนที่ไม่รู้ข้อมูล
mickmackusa

คำตอบ:


225

เนื่องจากคุณกำลังส่งสตริงเป็นอาร์กิวเมนต์ที่สองไปยังฟังก์ชันวันที่ซึ่งควรเป็นจำนวนเต็ม

วันที่สตริง (string $ format [, int $ timestamp = time ()])

ลองstrtotimeซึ่งจะแยกวิเคราะห์เกี่ยวกับคำอธิบายวันที่และเวลาที่เป็นข้อความภาษาอังกฤษลงในการประทับเวลา Unix (จำนวนเต็ม):

date("d", strtotime($_GET['start_date']));

1
ฉันได้รับข้อผิดพลาดเดียวกันในตัวสร้างของคลาสฉันกำลังดีบักและปัญหาในตัวสร้างนั้นคือฉันได้รับเป็นพารามิเตอร์และจำนวนเต็มpublic function __construct(int $someId....)
Marcos Di Paolo

ด้วยการพิมพ์พารามิเตอร์ใน PHP กลายเป็น 'บรรทัดฐาน' มากขึ้นสิ่งที่ @MarcosDiPaolo กล่าวถึงจะมีให้เห็นบ่อยขึ้นอย่างแน่นอน ของแถมที่ตายแล้วคือการติดตามสแต็กจะชี้ไปที่บรรทัดของการประกาศพารามิเตอร์ที่พิมพ์ไม่ถูกต้อง
parttimeturtle

ฉันยังไม่เข้าใจว่าการกระทำคืออะไรที่นี่ @parttimeturtle
Marcos Di Paolo

@MarcosDiPaolo ประเภทของพารามิเตอร์ที่คุณส่งผ่านไปยังตัวสร้างนั้นจะต้องตรงกับประเภทที่ระบุไว้ในนิยามฟังก์ชัน "4" ที่แสดงด้วยสตริงแตกต่างจาก 4 ที่แสดงด้วยจำนวนเต็ม ดังนั้นให้สอดคล้องกับนิยามฟังก์ชันหรือปิดชนิดที่เข้มงวดหากคุณต้องการรวมค่าที่ 'คล้ายกัน' อย่างแท้จริงเช่นสตริง "4" ถึงจำนวนเต็ม 4
parttimeturtle

9

คุณสามารถแก้ปัญหานี้ได้โดยใช้strtotime()ฟังก์ชัน

date("d", strtotime($_GET['start_date']));

7

$_GET['start_date']ไม่ได้เป็นตัวเลขเป็นทางออกของฉัน strtotimeแต่รูปแบบวันที่ไม่ได้รับการสนับสนุนโดย คุณจะต้องอีกรูปแบบวันที่เป็นรูปแบบที่ใช้การได้สำหรับstrtotimeหรือการใช้การรวมกันของระเบิด / mktime

ฉันสามารถเพิ่มตัวอย่างให้คุณได้หากคุณใจดีพอที่จะโพสต์รูปแบบที่คุณได้รับในปัจจุบัน


การแคสต์ไม่สามารถแก้ไขปัญหาได้เนื่องจาก PHP จะแคสต์โดยอัตโนมัติเมื่อส่งต่อไปยังเมธอด
JohnP

ฉันชอบที่คุณระบุว่าไม่มีรายละเอียดเพียงพอในคำถามที่จะให้คำตอบที่แน่นอน เนื่องจากตัวอย่างที่ทำซ้ำได้น้อยที่สุดนั้นไม่สมบูรณ์ ควรปิดคำถามนี้แทนคำตอบ การให้ผู้ใช้โพสต์คำถามที่สมบูรณ์ไม่ใช่เรื่องยาก แต่จะไม่มีแรงจูงใจให้ทำเช่นนั้นหากอาสาสมัครจะเริ่มตอบคำถาม // เดาล่วงหน้า
mickmackusa

5

ฉันเจอสถานการณ์เดียวกันนี้ (ในกรณีของฉันมีค่าวันที่ในฟิลด์ PHP ที่กำหนดเองในมุมมอง Drupal) และสิ่งที่ได้ผลสำหรับฉันคือการใช้ intval แทน strtotime เพื่อเปลี่ยนค่าเป็นจำนวนเต็ม - เพราะโดยพื้นฐานแล้วเป็นการประทับเวลา แต่อยู่ในรูปแบบของสตริงแทนที่จะเป็นจำนวนเต็ม เห็นได้ชัดว่าจะไม่เป็นเช่นนั้นสำหรับทุกคน แต่อาจคุ้มค่าที่จะลอง


เราไม่รู้ว่าเทคนิคนี้จะแก้ปัญหาของ OP ได้หรือไม่เนื่องจาก OP ไม่ได้ระบุค่าของข้อมูลที่ป้อน
mickmackusa

5

ข้อผิดพลาดนี้เกิดขึ้นเมื่อคุณทำการคำนวณด้วยตัวแปรที่ใช้ตัวอักษรรวมกับตัวเลข (ตัวเลขและตัวอักษร) ตัวอย่างเช่น 24kb, 886ab ...

ฉันพบข้อผิดพลาดในฟังก์ชันต่อไปนี้

function get_config_bytes($val) {
    $val = trim($val);
    $last = strtolower($val[strlen($val)-1]);       
    switch($last) {
        case 'g':
            $val *= 1024;
        case 'm':
            $val *= 1024;
        case 'k':
            $val *= 1024;
    }
    return $this->fix_integer_overflow($val);
}

แอปพลิเคชันอัปโหลดภาพ แต่ไม่ทำงานแสดงคำเตือนต่อไปนี้:

ใส่คำอธิบายภาพที่นี่

การแก้ไข:intval()ฟังก์ชั่นสารสกัดจากค่าจำนวนเต็มของตัวแปรที่มีข้อมูลที่เป็นตัวเลขและสร้างตัวแปรใหม่ที่มีค่าเหมือนกัน แต่แปลงเป็นจำนวนเต็มกับintval()ฟังก์ชั่น นี่คือรหัส:

function get_config_bytes($val) {
    $val = trim($val);
    $last = strtolower($val[strlen($val)-1]);
    $intval = intval(trim($val));
    switch($last) {
        case 'g':
            $intval *= 1024;
        case 'm':
            $intval *= 1024;
        case 'k':
            $intval *= 1024;
    }
    return $this->fix_integer_overflow($intval);
}

ดูเหมือนว่าคุณกำลังตอบคำถามอื่นไม่ใช่คำถามที่โพสต์ไว้ที่ด้านบนของหน้านี้ กรุณาตอบคำถามที่ถามเท่านั้น นี่คือเหตุผลที่เราต้องการให้ผู้ถามนำเสนอตัวอย่างที่ทำซ้ำได้น้อยที่สุดเพื่อให้คำตอบไม่แตกเป็นพัน ๆ ทิศทาง
mickmackusa

3

สิ่งนี้ช่วยฉันได้มาก -

$new_date = date_format(date_create($old_date), 'Y-m-d');

ที่นี่date_create()ให้คุณมีวัตถุวันที่สำหรับวันที่ที่กำหนดและdate_format()จะตั้งค่าในรูปแบบที่กำหนด

ตัวอย่างเช่น,

<?php
    $date = date_create("13-02-2013");  // DateTime Object ( [date] => 2013-02-13 00:00:00.000000 [timezone_type] => 3 [timezone] => America/New_York )
    echo date_format($date,"Y-m-d");    // 2013-02-13
?>

มันจะช่วยนักวิจัยได้มากหากคุณอธิบายตัวอย่างข้อมูลของคุณและเหตุใดจึงเป็นประโยชน์กับคุณ
mickmackusa

คุณแน่ใจได้อย่างไรว่าเทคนิคนี้จะใช้ได้ผลกับคำถามที่ถาม? OP ไม่ได้ประกาศข้อมูลอินพุต
mickmackusa

0

นี่เป็นคำถามเก่า แต่มีอีกวิธีหนึ่งที่ละเอียดอ่อนที่ทำให้ข้อความนี้เกิดขึ้นได้ มีการอธิบายไว้ค่อนข้างดีที่นี่ในเอกสารนี่ในเอกสาร

ลองนึกภาพสถานการณ์นี้:

try {
  // code that triggers a pdo exception
} catch (Exception $e) {
  throw new MyCustomExceptionHandler($e);
}

และMyCustomExceptionHandlerกำหนดไว้คร่าวๆเช่น:

class MyCustomExceptionHandler extends Exception {
  public function __construct($e) {
    parent::__construct($e->getMessage(), $e->getCode());
  }
}

สิ่งนี้จะทริกเกอร์ข้อยกเว้นใหม่ในตัวจัดการข้อยกเว้นที่กำหนดเองเนื่องจากExceptionคลาสคาดหวังตัวเลขสำหรับพารามิเตอร์ที่สองในตัวสร้าง แต่PDOExceptionอาจมีการเปลี่ยนประเภทการส่งคืนแบบไดนามิกของ$e->getCode()เป็นสตริง

วิธีแก้ปัญหานี้คือการกำหนดตัวจัดการข้อยกเว้นที่คุณกำหนดเองเช่น:

class MyCustomExceptionHandler extends Exception {
  public function __construct($e) {
    parent::__construct($e->getMessage());
    $this->code = $e->getCode();
  }
}

การอธิบายการจัดการข้อยกเว้นอาจช่วยในการทำความเข้าใจปัญหา แต่จะไม่สามารถแก้ไขปัญหาได้ นี่ไม่ใช่คำตอบเนื่องจากไม่ได้พยายามแก้ไขคำถามที่ถาม
mickmackusa

0

การส่งสตริงไม่จำเป็นต้องเป็นปัญหาหากมีเพียงตัวเลขเท่านั้น

อีกสาเหตุหนึ่งที่อาจเกิดขึ้นได้คือถ้าคุณมีช่องว่างก่อนหรือหลัง เช่น "1557399276"


คุณไม่ทราบค่าของข้อมูลที่ป้อน (เว้นแต่คุณจะทำงานในสำนักงานเดียวกันกับ OP) แทนที่จะเดาข้อบกพร่องของค่าที่ป้อนในคำตอบคุณควรแสดงความคิดเห็นไว้ใต้คำตอบที่ขอให้ OP ระบุข้อมูลอินพุตที่แน่นอน
mickmackusa

-1

หากข้อผิดพลาดเกิดขึ้นขณะคำนวณให้ตรวจสอบอีกครั้งว่าค่าไม่มีเครื่องหมายจุลภาค (,) ค่าต้องอยู่ในรูปแบบจำนวนเต็ม / จำนวนลอยเท่านั้น


ไม่มีข้อบ่งชี้ว่าค่าของ OP มีเครื่องหมายจุลภาค คุณกำลังคาดเดาปัญหา ในกรณีนี้คุณควรขอให้ OP ชี้แจงตัวอย่างที่ทำซ้ำได้น้อยที่สุดแทนที่จะโพสต์คำตอบ
mickmackusa

-1

คุณต้องตั้งค่าเขตเวลาโดยใช้ date_default_timezone_set ()


นี่ไม่ใช่ข้อผิดพลาดที่ขึ้นกับเขตเวลา
mickmackusa

-1

ถ้า $ _GET ['start_date'] เป็นสตริงให้แปลงเป็นจำนวนเต็มหรือสองเท่าเพื่อจัดการกับตัวเลข

$int = (int) $_GET['start_date']; //Integer
$double = (double) $_GET['start_date']; //It takes in floating value with 2 digits

คุณกำลังคาดเดามูลค่าของ$start_date. ถ้าเป็น08/08/2020แล้วการหล่อเป็นจำนวนเต็มหรือลอยจะไม่ช่วยเลย แทนที่จะตอบคำถามนี้การดำเนินการที่ถูกต้องคือการแสดงความคิดเห็นใต้คำถามเพื่อขอให้ OP แสดงข้อมูลที่ป้อนให้ถูกต้อง
mickmackusa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.