Docker Compose creates separate docker containers for different services, and each container is essentially just a separate computer that can connect with other computers (containers) through the docker virtual network.

------------------------------------------------------------
|                       your computer                      |
------------------------------------------------------------
                               |                    
        ------------ docker virtual network --------
        |                      |                   |
------------------- --------------------- ------------------
|  php container  | |  redis container  | |  db container  |
------------------- --------------------- ------------------

In the above setup these three containers are basically just separate computers on a network, thus for instance the PHP container isn't running Redis on "localhost"; Redis is instead running in the "redis" container (on a separate container/computer), and Postgres is running in it's own "db" container.

Looking at an example docker-compose.yml file defining a Redis service:

redis:
  build:
    context: .
    dockerfile: Dockerfile
  ports:
    - "6379:6379"

the ports configuration is binding port 6379 of the "redis" container to the same port your own computer, but not for the other containers. So while you can connect to Redis via localhost (127.0.0.1:6379, the php and db containers cannot access Redis similarly on their own localhost.

As the Networking in Docker Compose docs explain, each docker compose container can access other containers by using the service name as hostname. For example your PHP program can can access the database container using the hostname db, and connect to the redis container via it's hostname (docker-compose service name) redis - ex. $redis->connect('redis', 6379);.