ctype_graph
Checks whether every character in a string is printable and visible, with no whitespace.
ctype_graph(mixed $text): bool- Added in PHP 4.0.4
Parameters
| Parameter | Type | Description |
|---|---|---|
$text | mixed | The string to test. Every byte must produce visible ink for the result to be true. An int between -128 and 255 is interpreted as an ASCII codepoint, which is why non-string arguments are deprecated as of PHP 8.1. |
Return value
booltrue if every character in text is printable and actually creates visible output, with no whitespace, false otherwise. An empty string always returns false.
Errors
Never throws. A non-string argument raises an E_DEPRECATED notice as of PHP 8.1; values that are neither string nor int return false.
Changelog
- PHP 8.1Passing a non-string argument is deprecated. Ints between -128 and 255 are still read as ASCII codepoints, so cast to string or use chr() explicitly.
ctype_graph() is ctype_print() minus the space: it is true when every character produces visible output. Over ASCII that is codepoints 33 to 126 — letters, digits and punctuation, but not the space, tab, newline or any control character.
When to reach for it
It is the natural check for values that must be a single unbroken token: an API key, a password, a CLI flag, a URL slug, a header token, a filename you are about to write. Those values may legitimately contain punctuation, so ctype_alnum() is too strict, but they must not contain a space or a stray newline, so ctype_print() is too loose.
What trips people up
People reach for trim() and assume the value is now space-free. trim() only removes whitespace from the ends; ctype_graph() also catches whitespace in the middle, which is exactly where a copy-pasted key tends to break.
As with the rest of the family, this is a byte test. UTF-8 punctuation such as a typographic quote is multi-byte and will fail even though it looks perfectly visible.
Example
When to use it
- Validating a pasted API token that must contain no whitespace anywhere
- Rejecting filenames that contain spaces before writing them to disk
- Checking a CLI argument is a single unbroken token before passing it on
Frequently asked questions
What is the difference between ctype_graph and ctype_print?
Only the space character. ctype_print accepts it, ctype_graph does not; both reject control characters such as tab and newline.
Does ctype_graph accept punctuation?
Yes. Any visible ASCII character from 33 to 126 passes, which includes all punctuation and symbols as well as letters and digits.
Why does ctype_graph fail on a string that looks like it has no spaces?
It is usually an invisible character — a non-breaking space, a trailing carriage return from a Windows file, or a multi-byte UTF-8 character. Run bin2hex() on the value to see the actual bytes.
More examples
graph vs print vs punct on the same characters
The space row shows graph=0 print=1, the only place the two disagree. The tab row is 0 everywhere because it is a control character, and '!' is the only row where punct is 1.
<?php
foreach ([' ', 'A', '!', "\t"] as $ch) {
printf("%-6s graph=%d print=%d punct=%d\n",
json_encode($ch),
ctype_graph($ch),
ctype_print($ch),
ctype_punct($ch));
}Catching whitespace that trim would miss
trim() removes the outer padding but the space inside the token remains, so ctype_graph returns false and the script reports that the key is still broken. This is the failure mode trim() alone will not catch.
<?php
$key = " sk_live_ab 12 ";
$trimmed = trim($key);
var_dump($trimmed);
var_dump(ctype_graph($trimmed));
echo ctype_graph($trimmed)
? "Usable key\n"
: "Key still contains whitespace\n";
Discussion