Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Column 'present' cannot be null means MySQL received a SQL NULL for a column defined NOT NULL when PHP executed the prepared statement. The constraint is working; it does not make the PHP variable non-null. In the SitePoint example, the exception identifies present, so inspect the value and parameter passed for that column at the exact execute() call.

What the error means

The SitePoint thread reports MySQL error 1048 with SQLSTATE 23000 for the present column. MySQL’s 8.4 Error Reference identifies 1048 as ER_BAD_NULL_ERROR and gives the message template “Column ‘%s’ cannot be null”. The message means a NULL value reached a column that rejects it; it does not indicate that the database has failed to enforce NOT NULL.

The PHP code in the forum prepares an attendance-row insert and binds named parameters, but the discussion does not establish one definitive application-level cause. Treat it as a runtime parameter-flow problem: trace the value assigned to present and how it reaches the statement.

Trace the value at the failing execution

  1. Read the complete exception. Note the column named in the message, SQLSTATE, MySQL error number, and the line where execute() fails. In this case, begin with present.
  2. Inspect the actual value and type immediately before execution. In development, use var_dump($present) or log a safely redacted diagnostic. Check whether it is null, an empty string, or a valid value. Avoid exposing personal data in logs.
  3. Follow every assignment path. Verify form field names, validation and isset() checks, branch conditions, variable scope, and whether every path assigns $present before the insert.
  4. Check the parameter mapping. Make sure the placeholder for present is bound to the intended variable, and that the insert’s columns and values correspond.

Account for bindParam() timing

PDOStatement::bindParam() binds a variable by reference. PHP’s manual says the variable is evaluated when PDOStatement::execute() is called. That means the value at execution matters, not necessarily the value when bindParam() ran. If the variable changes between binding and execution—or is never assigned on a particular branch—trace that timing carefully. bindValue(), by contrast, associates a value with the parameter when called. See the PHP Manual entry for bindParam().

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Pass a complete parameter set for a simple insert

For a straightforward insert, passing the values together to execute() makes it easier to see what reaches the database at the point of execution:

$stmt = $pdo->prepare(
    'INSERT INTO attendance (member_id, member_email, member_phone, present, attend_state)
     VALUES (:member_id, :member_email, :member_phone, :present, :attend_state)'
);

$stmt->execute([
    'member_id' => $memberId,
    'member_email' => $memberEmail,
    'member_phone' => $memberPhone,
    'present' => $present,
    'attend_state' => $attendState,
]);

Alternatively, bind parameters explicitly and then call execute() without passing an array. Use one style consistently so it is clear which values are supplied. PHP documents that values passed in the execute() array are treated as PDO::PARAM_STR; use explicit bindValue() types when you need deliberate type handling. See PDOStatement::execute().

Do not substitute an empty string for NULL

NULL, '', and a meaningful false-like value are different. In the forum thread, assigning empty strings led to a different error: MySQL rejected the empty string as an incorrect integer value for present. Do not use '' as a generic fix. Check the column’s type, constraints, defaults, and the application’s meaning for the field. If it represents a boolean-like state, provide an intentional valid value such as 0 or 1 only if that matches the schema and business rules.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Keep the prepared statement

Do not fix the error by interpolating user input into SQL. Keep using placeholders and pass input as parameters; PHP’s PDO::prepare() documentation recommends prepared statements for this purpose. The repair is to ensure the statement receives the intended, schema-compatible value—not to remove parameterization or weaken a database constraint without a deliberate design reason.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.