どうやら UTF-8 に対して strlen を使用するとバイト数がおかしくなるらしい。
UTF-8 は文字によってバイト数がバラバラで、1~6バイトまであるそうな。
どうやらこれが原因らしい。
なので strlen を使用して「2バイトなら全角、1バイトなら半角」の様な判定をしようとするとうまくいかない。
なので下記の様に一度 sjis に変換して strlen を使用すると正常なバイト数が取得できる。
strlen(mb_convert_encoding($str,"UTF-8","SJIS"));
追記
mb_strlen() という関数があるというコメントを頂きました。