Run add_action hook if condition

I’d guess this code is being run directly from your plugin’s functions.php, meaning that you’re evaluating is_front_page() and is_archive() as you load the plugin. That’s too early – that’s before enough state has been initialised to know which page you’re on.

To fix this, you either need to:

  1. move the logic into your say_hello functions, and check is_front_page or is_archive at the point that you’re rendering the header or footer:
function say_hello_in_header() {
    // Echo in wp_head on the front page
    if ( is_front_page() ) {
        echo '<p>Hello!</p>';
    }
}
add_action( 'wp_head', 'say_hello_in_header' );

function say_hello_in_footer() {
    // Echo in wp_footer on the archive
    if ( is_archive() ) {
        echo '<p>Hello!</p>';
    }
}
add_action( 'wp_footer', 'say_hello_in_footer' );
  1. or pick an action to hook that’s after all of the state has been set up but before the header and footer have been rendered, e.g. wp_enqueue_scripts, and perform the tests and the head and footer actions there:
function enqueue_say_hellos() {
    // Echo in wp_head on the front page
    if ( is_front_page() ) {
        add_action( 'wp_head', 'say_hello' );
    }

    // Echo in wp_footer on the archive
    if ( is_archive() ) {
        add_action( 'wp_footer', 'say_hello' );
    }
}
add_action( 'wp_enqueue_scripts', 'enqueue_say_hellos' );

That all said, please note that wp_head is not the correct place to add HTML to the page, since it’s run from the page’s <head> tag and not the <body> tag. Any content you add there will appear in the wrong place if at all. If you want to modify the header on your page you’ll have to edit your template or find some other mechanism.