Shuffle array without duplicates
There is one bug, in that the function doesn't quite do what you want it to. It does not loop though the randomized array, persisting the order until you've reached the end. As you seem to want from your description. What it does do is to randomize the array once, then once more if there is no array index 0 (which is only true if the array is empty). Then it retrieves the first image ID from the array, increases the counter, generates the URL. Before it finally promptly forgets everything done inside the function, except the finalized URL.

If you want true persistence on the order of images, then you need to store it somewhere. Either in the session, or in a database.

As for the last two questions, I've refactored your code to be more in line with recommended practices:

function randomImageLink ($width, $height, $images) {
    // Using mt_rand () instead of array_rand () due to randomization issues.
    $loc = mt_rand (0, count ($images) - 1);

    // Get a random image ID from the array.
    $id = $images[$loc];

    return 'https://unsplash.it/' . $width . '/' . $height . '?image=' . $id;
}

$imageList = [1048, 1049, 1061, 1064, 983, 972, 964];
$imageLink = randomImageLink (800, 600, $imageList);


Note that this is based upon the function you wrote, not the function you wanted. It should, however, work as an example on how you can restructure your code in general. 

PS: I've assumed that the list of image IDs come from a external source, such as a "glob()" on a folder or a DB query.