The key and value in the postmeta table are technically always strings. even if you were to cast your string to an int it would be cast to a string by the query. Try:
$args = array (
'post_type' => 'post',
'meta_query' => array (
array (
'key' => 'related_page',
'value' => 1,
)
),
);
$posts = new WP_Query( $args );
var_dump($posts->request);
You will notice CAST(wp_postmeta.meta_value AS CHAR) = '1') in that request.
You have to use the type argument to get the query to treat the value as a number. Even with 'type' => 'NUMERIC' you will notice that the value is still treated as a string but cast by the query– CAST(wp_postmeta.meta_value AS SIGNED) = '1').
And none of this really effects the data returned. Try:
update_post_meta(1,'hal9000',1);
var_dump(get_post_meta(1,'hal9000'));
Put in an integer, get back a string.
PHP is very forgiving about “type” so in many cases it doesn’t matter whether you have a string or a int. The big case where it does matter, that I can think of, is sorting. Or, maybe, the case that shows up most on this site. You will need to cast to a integer– use type if you need the query to sort– or sorting will be alphabetical and not numeric which do not always align.