156

I have a form that passes two dates (start and finish) to a PHP script that will add those to a DB. I am having problems validating this. I keep getting the following error:

A non well formed numeric value encountered

This is when I use the following

date("d",$_GET['start_date']);
desertnaut
  • 57,590
  • 26
  • 140
  • 166
Deviland
  • 3,324
  • 7
  • 32
  • 53
  • 1
    I assume your `$_GET['start_date']` is not a [timestamp](http://en.wikipedia.org/wiki/Timestamp) which is expected by `date` function as a second argument – Nemoden May 26 '11 at 09:36

10 Answers10

271

This error means you are trying to use a string that contains a non-numeric value where only a number is expected.

Like in your case: date() expects a number (a unix timestamp) while you are passing a string, something like 2020-10-10 or 2020/10/10.

Every time you encounter such a problem you must investigate it. First of all, print the problem value using var_dump(). Then you must decide, what to do next.

  • if you are accessing a wrong variable, like some function returns an array but you are trying to use it as a number, use var_dump() result to learn the array's structure and to find the right element to use.
  • if the problem value can be converted to a number, then do it. Like in your case, use strtotime() to convert a string date representation to a number of seconds
  • if it cannot be converted, being plainly wrong, you need to fix the cause:
    • if the problem value is coming from outside, like, in the form field named 'age' someone enters twenty two, you need to validate the entered value, check if it's indeed a number and stop the form processing in case it's not, and inform the user that entered data is invalid
    • if some your function returns incorrect value, like, $22 instead of 22, you must fix that function or change the logic of your application: you must do all calculations first, and format the numbers later.

What you should never do is just mindlessly cast the problem value to a number, as suggested in some answers. Casting won't fix the problem. It will just sweep it under the rug and often will give you outright incorrect value. Besides, casting effectively works as error suppression, so when some your function will start returning incorrect value, casting will start silently returning 0, leaving you unaware of the problem.

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
DChaplin
  • 2,726
  • 2
  • 13
  • 2
  • 1
    I get the same error in the constructor of a class, i was debugging and the problem in that constructor is I'm receiving as a parameter and integer `public function __construct(int $someId....)` – Marcos Di Paolo Apr 23 '20 at 20:35
  • With parameter typing in PHP becoming more the 'norm', what @MarcosDiPaolo mentioned will definitely be seen more frequently. A dead giveaway is the stack trace will point to the line of the parameter declaration that's being incorrectly typed. – parttimeturtle May 05 '20 at 07:27
  • I still don't understand what is the course of action here @parttimeturtle – Marcos Di Paolo May 05 '20 at 17:56
  • @MarcosDiPaolo the Types of parameters you pass to that constructor must match the Types that are being hinted in the function definition. "4" represented by a string is different from 4 represented by an integer. So either conform to the function definition or turn off strict types, if you truly need to coalesce 'similar' values, e.g. string "4" to integer 4. – parttimeturtle May 18 '20 at 19:36
  • `PDO_Statement::bindParam()` Also throws this when the fourth argument is not an (int) – Richard Tyler Miles Aug 06 '21 at 16:29
8

This error occurs when you perform calculations with variables that use letters combined with numbers (alphanumeric), for example 24kb, 886ab ...

I had the error in the following function

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);
}

The application uploads images but it didn't work, it showed the following warning:

enter image description here

Solution: The intval() function extracts the integer value of a variable with alphanumeric data and creates a new variable with the same value but converted to an integer with the intval() function. Here is the code:

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);
}

The function fix_integer_overflow

// Fix for overflowing signed 32 bit integers,
// works for sizes up to 2^32-1 bytes (4 GiB - 1):
protected function fix_integer_overflow($size) {
    if ($size < 0) {
        $size += 2.0 * (PHP_INT_MAX + 1);
    }
    return $size;
}
Vladimir Salguero
  • 5,609
  • 3
  • 42
  • 47
  • It appears that you are answering a different question -- not the one posted at the top of this page. Please only answer the question that is asked. This is why we require askers to provide a [mcve] -- so that the answers don't splinter into a thousand different directions. – mickmackusa Aug 17 '20 at 08:10
  • 1
    the function depends on external code ... what does `$ this-> fix_integer_overflow` do? – Lorenzo Magon Apr 22 '21 at 08:47
  • Hi Lorenzo Magon, I add the function `fix_integer_overflow`, so you can see its use – Vladimir Salguero Apr 22 '21 at 13:30
  • Casting is a very wrong idea. It sweeps the problem under the rug. Instead of just casting, you must parse the string according to the expected format and validate results. For example, your own function doesn't parse the example provided in the question, 24kb, returning outright incorrect result of 24. – Your Common Sense May 22 '23 at 06:15
8

$_GET['start_date'] is not numeric is my bet, but an date format not supported by strtotime. You will need to re-format the date to a workable format for strtotime or use combination of explode/mktime.

I could add you an example if you'd be kind enough to post the format you currently receive.

Geoffrey Hale
  • 10,597
  • 5
  • 44
  • 45
Wesley van Opdorp
  • 14,888
  • 4
  • 41
  • 59
  • Casting won't fix the issue since PHP will automatically cast it when passed to the method. – JohnP May 26 '11 at 09:36
  • I like that you identified that there isn't enough detail in the question to offer an exact answer. This is because the [mcve] is incomplete; ergo this question should be closed instead of answered. It's not hard to get users to post a complete question, but they will not be motivated to do so if volunteers will start firing answers//guesses in advance. – mickmackusa Aug 17 '20 at 08:22
5

I ran into this same situation (in my case with a date value in a custom PHP field in a Drupal view), and what worked for me was using intval instead of strtotime to turn the value into an integer - because it basically was a timestamp, but in the form of a string rather than an integer. Obviously that won't be the case for everyone, but it might be worth a try.

spidersilk
  • 61
  • 1
  • 4
  • We do not know if this technique will resolve the OP's problem because the OP did not state the value of the input data. – mickmackusa Aug 17 '20 at 08:19
5

This helped me a lot:

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

Here, date_create() provides you a date object for a given date & date_format() will set it in a given format.

for example,

<?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
?>
desertnaut
  • 57,590
  • 26
  • 140
  • 166
Tushar Walzade
  • 3,737
  • 4
  • 33
  • 56
-1

This is an old question, but there is another subtle way this message can happen. It's explained pretty well here, in the docs.

Imagine this scenerio:

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

And MyCustomExceptionHandler is defined roughly like:

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

This will actually trigger a new exception in the custom exception handler because the Exception class is expecting a number for the second parameter in its constructor, but PDOException might have dynamically changed the return type of $e->getCode() to a string.

A workaround for this would be to define you custom exception handler like:

class MyCustomExceptionHandler extends Exception {
  public function __construct($e) {
    parent::__construct($e->getMessage());
    $this->code = $e->getCode();
  }
}
Parris Varney
  • 11,320
  • 12
  • 47
  • 76
  • Explaining exception handling may aid in understanding the problem, but it will not resolve the problem. This is Not An Answer because it does not attempt to resolve the question asked. – mickmackusa Aug 17 '20 at 08:18
-1

if $_GET['start_date'] is a string then convert it in integer or double to deal numerically.

$int = (int) $_GET['start_date']; //Integer
$double = (double) $_GET['start_date']; //It takes in floating value with 2 digits
A.Aleem11
  • 1,844
  • 17
  • 12
  • You are guessing at the value of `$start_date`. If it is `08/08/2020` then casting it as an integer or a float will not help at all. Rather than answer this question, the correct action would be to leave a comment under the question to ask the OP to express the exact input data. – mickmackusa Aug 17 '20 at 08:15
  • $end_suggest_time = (int) $rowone['start_suggest_time'] + (24 * 3600); when i add (int) in the previus of $rowone i dont recieve this error "Notice: A non well formed numeric value encountered in" – God is universe programmer Feb 16 '22 at 02:29
-1

in the name of the universe programmer

in my case i receive this error

"Notice: A non well formed numeric value encountered in"

my code with above error:

$end_suggest_time = $rowone['start_suggest_time'] + (24 * 3600);

when i add (int) in the previous of $rowone['start_suggest_time'] I don't receive this error

"Notice: A non well formed numeric value encountered in"

$end_suggest_time = (int) $rowone['start_suggest_time'] + (24 * 3600);

dazed-and-confused
  • 1,293
  • 2
  • 11
  • 19
-1

In my case when getting error:

A non well formed numeric value encountered

When my code is like this

if (date('y-m-d H:i:s') - $user_token['created_at'] < (60 * 60 * 24)) {
...
}

And my fixing code

date_default_timezone_set('Asia/Jakarta');
if (strtotime(date('y-m-d H:i:s')) - strtotime($user_token['created_at']) < (60 * 60 * 24)) {
...
}
Hana Hasanah
  • 145
  • 1
  • 6
  • This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://stackoverflow.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://stackoverflow.com/help/whats-reputation), you can also [add a bounty](https://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/late-answers/32484372) – rak007 Aug 19 '22 at 12:29
-2
<td>{{(double)$template_list->administrative_approval - (double)$template_list->released_fund }} </td>

(double),(int) use its.

General Grievance
  • 4,555
  • 31
  • 31
  • 45