Signature
ctype_print(mixed $text): boolPurpose
ctype_print() answers one question: does every character in a string produce visible output or a blank? Letters, digits, punctuation and the ordinary space all count as printable. Control characters such as newline, tab, carriage return, NUL and DEL do not. It is a quick, dependency-light way to reject text that would break a single-line display, a log entry or a simple label field.
The function belongs to the ctype extension, which classifies characters byte by byte. It does not parse, trim or normalize anything. It only inspects the string and returns a boolean.
Signature
Parameters and defaults
$text is the value to test. It has no default, so you must always pass it. In normal use it is a string, and every byte of that string must be printable for the result to be true.
The parameter is declared as mixed for historical reasons. The manual describes a legacy behavior for integers: a value between -128 and 255 is treated as the ASCII code of one character (negative values have 256 added), and any other integer is treated as a string of its decimal digits. Since PHP 8.1 passing a non-string argument is deprecated, and the manual says it will eventually be read as a string. Do not rely on it. Cast explicitly with (string) when you mean digits, or call chr() when you mean a single character code.
Return value and failure cases
The function returns true when every character in the string would create output, blanks included. It returns false when the string contains a control character or a character with no output or control function. An empty string always returns false, which surprises people who expect a vacuous truth.
There is no exception and no warning for ordinary strings. Failure is expressed only through the false result, so you cannot tell from the return value which character caused it.
Example 1: basic checks
Spaces are printable, but newline and tab are not.
$tests = [
'plain' => 'Hello, World!',
'with space' => 'abc 123',
'with newline' => "abc\n",
'with tab' => "a\tb",
];
$result = [];
foreach ($tests as $label => $value) {
$result[$label] = ctype_print($value);
}
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"plain":true,"with space":true,"with newline":false,"with tab":false}
Example 2: boundaries and the empty string
The tilde is the last printable ASCII character, while DEL (\x7F) and the characters below space are control characters. The empty string fails.
$values = ['', ' ', '~', "\x7F", "\x1F", "\0"];
$out = [];
foreach ($values as $v) {
$out[] = ctype_print($v);
}
echo json_encode($out), "\n";[false,true,true,false,false,false]
Example 3: validating a one-line label
Because a space counts as printable, a string made only of spaces passes ctype_print(). A practical validator often adds a check for that.
function isSingleLineLabel(string $text): bool
{
return ctype_print($text) && trim($text) !== '';
}
$inputs = ['Invoice 2024', ' ', "Line1\nLine2", ''];
$results = array_map('isSingleLineLabel', $inputs);
echo json_encode($results), "\n";[true,false,false,false]
Edge cases
- Empty string: always
false. Handle it separately if empty input should mean something else. - Whitespace-only text: a run of ordinary spaces is printable, so it returns
true. Newlines, tabs and carriage returns are control characters and returnfalse. - Non-ASCII bytes: ctype functions classify single bytes, and results for bytes above 127 can depend on the current locale. A UTF-8 character is several bytes, so do not treat
ctype_print()as a Unicode-aware check. Keep it for ASCII validation, or use a multibyte-aware tool such asIntlChar::isprint()when you need code point semantics. - Numeric values: an integer argument is deprecated and may be read as an ASCII code, which is almost never what you want. Convert to a string first.
Common mistakes
- Assuming it rejects blank input. It rejects an empty string, but not a string of spaces.
- Passing numbers directly.
ctype_print(65)does not mean the digits 6 and 5 under the legacy rule. Cast to string for digits or usechr()for a character code. - Using it on multibyte text. Accented letters, emoji and other non-ASCII text are not reliably judged byte by byte.
- Confusing it with
ctype_graph().ctype_graph()excludes the space;ctype_print()includes it. A string likea bpasses the print check but fails the graph check. - Expecting a reason for failure. The function only returns a boolean, so locate the offending character yourself if you need to report it.
Related functions
ctype_cntrl()checks for control characters.ctype_graph()checks for printable characters except space.ctype_punct()checks for printable characters that are neither whitespace nor alphanumeric.IntlChar::isprint()checks whether a code point is printable.
Recap
ctype_print() returns true only when the string is non-empty and every character is printable, spaces included. Control characters and the empty string give false. Pass real strings, stay with ASCII, and add a trim() check when blank-only values should be rejected.
Tested examples
$tests = [
'plain' => 'Hello, World!',
'with space' => 'abc 123',
'with newline' => "abc\n",
'with tab' => "a\tb",
];
$result = [];
foreach ($tests as $label => $value) {
$result[$label] = ctype_print($value);
}
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"plain":true,"with space":true,"with newline":false,"with tab":false}
$values = ['', ' ', '~', "\x7F", "\x1F", "\0"];
$out = [];
foreach ($values as $v) {
$out[] = ctype_print($v);
}
echo json_encode($out), "\n";[false,true,true,false,false,false]
function isSingleLineLabel(string $text): bool
{
return ctype_print($text) && trim($text) !== '';
}
$inputs = ['Invoice 2024', ' ', "Line1\nLine2", ''];
$results = array_map('isSingleLineLabel', $inputs);
echo json_encode($results), "\n";[true,false,false,false]