Signature
ctype_graph(mixed $text): boolPurpose
ctype_graph() answers a narrow question: does every character in a string produce visible output? Letters, digits and punctuation qualify. Spaces, tabs, newlines and other control characters do not. It is useful for validating identifiers, tokens and codes where whitespace must never appear.
The function is part of the ctype family. These functions are fast, simple character-class checks that return a boolean and do not use regular expressions.
Signature
Parameters and defaults
$text is the only parameter, and it has no default. It is the string to test. The function returns true only when every character in the string is printable and visible.
The parameter is typed mixed for historical reasons. Older code could pass an integer, which was treated as an ASCII code if it fell between -128 and 255, and as a string of decimal digits otherwise. Since PHP 8.1 passing a non-string argument is deprecated, and the manual says a future version will treat it as a string. Pass strings only. If you start from another type, cast it with (string) or use chr() when you mean a character code.
Return value and failure cases
The function returns a bool:
truewhen the string is non-empty and every character is printable and not whitespace.falsewhen any character is a space, tab, newline, carriage return or other non-visible character.falsefor an empty string. This is easy to overlook, because many "all characters match" checks are true for empty input, but this one is not.
It does not throw for ordinary strings. The only failure to watch for is the deprecation notice when a non-string is passed.
Example 1: basic checks
This example tests several strings and prints the results as JSON. Note that the string containing a space fails, and so does the empty string.
$values = ['abc123', 'LKA#@%.54', 'hello world', "tab\t", ''];
$results = [];
foreach ($values as $value) {
$results[] = ctype_graph($value);
}
echo json_encode($results), "\n";[true,true,false,false,false]
Example 2: validating a token safely
Because non-string arguments are deprecated, a helper that guards the type first keeps your code forward compatible. This helper accepts only strings with no whitespace.
function isSafeToken(mixed $token): bool
{
return is_string($token) && ctype_graph($token);
}
$inputs = ['api_key-42', 'api key', "line\nbreak", 'ok!', 42];
$report = [];
foreach ($inputs as $input) {
$report[] = isSafeToken($input) ? 'valid' : 'invalid';
}
echo json_encode($report), "\n";["valid","invalid","invalid","valid","invalid"]
The integer 42 is rejected by is_string() before ctype_graph() ever sees it, so no deprecation is triggered.
Example 3: comparing with related checks
The differences between ctype_graph(), ctype_print() and ctype_alnum() are small but important. A space is printable, so ctype_print() accepts it, but it creates no visible mark, so ctype_graph() rejects it. Punctuation passes ctype_graph() but fails ctype_alnum().
$samples = ['a b', 'a-b', 'ab', ' '];
$rows = [];
foreach ($samples as $s) {
$rows[] = [
'graph' => ctype_graph($s),
'print' => ctype_print($s),
'alnum' => ctype_alnum($s),
];
}
echo json_encode($rows), "\n";[{"graph":false,"print":true,"alnum":false},{"graph":true,"print":true,"alnum":false},{"graph":true,"print":true,"alnum":true},{"graph":false,"print":true,"alnum":false}]
Edge cases
- Empty string: always
false. If empty input should be allowed, test for it separately before calling the function. - Single space:
false, even thoughctype_print()returnstruefor it. - Trailing newline: a string such as
"abc\n"fails. Input read from forms or lines of text often carries one, so trim it first if that is acceptable. - Integers: an int is treated as a character code or as digits depending on its range, which is confusing and now deprecated. Avoid it.
- Non-ASCII text: the check works on individual single-byte characters. Do not rely on it to classify multibyte Unicode text. For code point level checks, the manual points to
IntlChar::isgraph(), or you can use a Unicode-aware regular expression.
Common mistakes
- Assuming empty strings pass. They do not, so required and optional fields need separate handling.
- Confusing it with
ctype_print(). If spaces must be rejected, usectype_graph(). If spaces are fine, usectype_print(). - Passing numbers directly. A value like
65may be treated as the letterArather than as the text "65". Cast with(string)when you mean text. - Expecting it to verify format. It only says that characters are visible. It cannot tell you whether a string is a valid email address or a well-formed token.
- Forgetting leftover newlines. A single trailing line break makes the whole string invalid.
Related functions
ctype_alnum()checks for letters and digits only.ctype_print()checks for printable characters, including space.ctype_punct()checks for printable characters that are neither whitespace nor alphanumeric.IntlChar::isgraph()checks whether a Unicode code point is a graphic character.
Recap
ctype_graph() returns true when a non-empty string contains only visible, printable characters and no whitespace. Pass real strings, remember that empty input is false, and choose ctype_print() instead when spaces should be accepted.
Tested examples
$values = ['abc123', 'LKA#@%.54', 'hello world', "tab\t", ''];
$results = [];
foreach ($values as $value) {
$results[] = ctype_graph($value);
}
echo json_encode($results), "\n";[true,true,false,false,false]
function isSafeToken(mixed $token): bool
{
return is_string($token) && ctype_graph($token);
}
$inputs = ['api_key-42', 'api key', "line\nbreak", 'ok!', 42];
$report = [];
foreach ($inputs as $input) {
$report[] = isSafeToken($input) ? 'valid' : 'invalid';
}
echo json_encode($report), "\n";["valid","invalid","invalid","valid","invalid"]
$samples = ['a b', 'a-b', 'ab', ' '];
$rows = [];
foreach ($samples as $s) {
$rows[] = [
'graph' => ctype_graph($s),
'print' => ctype_print($s),
'alnum' => ctype_alnum($s),
];
}
echo json_encode($rows), "\n";[{"graph":false,"print":true,"alnum":false},{"graph":true,"print":true,"alnum":false},{"graph":true,"print":true,"alnum":true},{"graph":false,"print":true,"alnum":false}]