Вместо нескольких if / else вы можете поместить все правило в массив для простоты поддержки.
$array = [
1 => [
4 => 'img/s1.jpg',
12 => 'img/s12.jpg',
14 => 'img/s14.jpg',
],
2 => [
2 => 'img/c2.jpg'
]
];
function getDayDateImage($array, $d, $h)
{
while (!$array[$d][$h]) {
$h--;
if ($h < 0) {
$h = 23;
$d--;
}
if ($d < 1) {
return 'img/rest.jpg'; // Default
}
}
return $array[$d][$h];
}
echo getDayDateImage($array, 1, 1); // Get img/rest.jpg
echo getDayDateImage($array, 1, 13); // Get img/s12.jpg
echo getDayDateImage($array, 2, 1); // Get img/s14.jpg
echo getDayDateImage($array, 2, 4); // Get img/c2.jpg
//Just pass you $d and $h
//getDayDateImage($array, $d, $h);
Надеюсь, что это поможет.
Этот код работает, увеличивая время ожидания, когда ожидалось (это модифицированная версия примера, который я связал в вопросе):
// copied from Mono, because CF lacks this enum
enum SocketError
{
IOPending = 997,
NoBufferSpaceAvailable = 10055,
TimedOut = 10060,
WouldBlock = 10035
}
// milliseconds
int receiveTimeout = 20000;
int sendTimeout = 20000;
public override int Read(byte[] buffer, int offset, int size)
{
int startTickCount = Environment.TickCount;
int received = 0;
do
{
List<Socket> sock = new List<Socket>(new Socket[] {socket});
Socket.Select(sock, null, null, receiveTimeout*1000 + 1);
if (Environment.TickCount > startTickCount + receiveTimeout)
throw new SocketException((int) SocketError.TimedOut);
try
{
received += socket.Receive(buffer, offset + received,
size - received, SocketFlags.None);
}
catch (SocketException ex)
{
if (ex.ErrorCode == (int) SocketError.WouldBlock ||
ex.ErrorCode == (int) SocketError.IOPending ||
ex.ErrorCode == (int) SocketError.NoBufferSpaceAvailable)
{
// socket buffer is probably empty, wait and try again
Thread.Sleep(30);
}
else
throw; // any serious error occurr
}
} while (received < size);
return received;
}
public override void Write(byte[] buffer, int offset, int size)
{
int startTickCount = Environment.TickCount;
int sent = 0;
do
{
List<Socket> sock = new List<Socket>(new Socket[] {socket});
Socket.Select(null, sock, null, sendTimeout*1000 + 1);
if (Environment.TickCount > startTickCount + sendTimeout)
throw new SocketException((int) SocketError.TimedOut);
try
{
sent += socket.Send(buffer, offset + sent,
size - sent, SocketFlags.None);
}
catch (SocketException ex)
{
if (ex.ErrorCode == (int) SocketError.WouldBlock ||
ex.ErrorCode == (int) SocketError.IOPending ||
ex.ErrorCode == (int) SocketError.NoBufferSpaceAvailable)
{
// socket buffer is probably full, wait and try again
Thread.Sleep(30);
}
else
throw; // any serious error occurr
}
} while (sent < size);
}
Ключевым элементом, отсутствующим в найденном мной примере, является Socket.Select (IList checkRead, IList checkWrite, IList checkError, int microSeconds)
. Имейте в виду, что этот метод может изменять переданный ему список (поэтому мой код каждый раз создает новый) и измеряет время в микросекундах, а не в миллисекундах. И не забудьте использовать Environment.TickCount
(который является источником монотонного времени ) вместо DateTime.Now
для измерения времени.