Você deve evitar tentar fazer isso com PHP. Quando o PHP se envolve, já é tarde demais - a memória já foi alocada.
Você pode banir endereços IP em qualquer camada, mas o nível mais baixo que utiliza a menor quantidade de recursos é o caminho que você deseja seguir. Este é geralmente o firewall. No mínimo, iptables (firewall linux) é o que você deseja usar. Existem ferramentas mencionadas por outros, como Fail2Ban, que podem automatizar isso para você. Firewall externo seria melhor.
Além de tentar proibir endereços IP ofensivos, tente usar melhor seus recursos. Se uma solicitação consumir menos recursos, levará mais tempo para que um ataque seja eficaz.
O Apache também usa muita memória. Se você estiver usando o mod_php, é ainda pior porque o PHP é carregado dentro de cada processo filho do Apache. Isso significa que mesmo solicitações de conteúdo estático (css / js / images) estão carregando o PHP, mesmo quando o PHP não está sendo usado. Você pode resolver esse problema usando o FastCGI. mod_fcgid é uma boa opção.
Existem também outros servidores Web que são mais eficientes em termos de recursos. Nginx é o meu favorito. Há também o Lighttpd. Muita gente como Litespeed (substitui o Apache).
Se você quiser ficar com o Apache, considere ajustá-lo da melhor maneira possível. Considere desativar o .htaccess. Aqui está uma boa explicação do porquê .