Autor Beitrag
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 25.06.23 23:57 
Moin!

Ich quäle mich grade durch die PHP8-Umstellung eines großen Projektes (von PHP7.4.33). Ich kann nachvollziehen, dass der Hinweis (E_NOTICE) für "undefined array key" auf eine Warnung (E_WARNING) hochgestuft wurde. Ich habe sogar tatsächlich deshalb Fehler im Code gefunden, die dort seit Jahren schlummerten (sie waren nicht wirklich schlimm, sonst wären sie ja schon vorher aufgefallen :zwinker:). Aber, immerhin. :mahn:

Nun gibt es aber Situationen, in denen will mir einfach nicht einleuchten, was daran nun "besser" sein soll. Konkret ärgere ich mich immer wieder bei Histogrammen, also dem Zählen der Häufigkeit unbekannter Werte. Hier ein simples Beispiel:
ausblenden PHP-Quelltext
1:
2:
3:
4:
5:
6:
$a = array('Apfel''Birne''Apfel');
$histo = array();
foreach ($a as $key)
  $histo[$key]++;
var_dump($a);
var_dump($histo);
liefert erwartungsgemäß unter PHP8.x:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
Warning:  Undefined array key "Apfel" in php8_count_demo.php on line 7
Warning:  Undefined array key "Birne" in php8_count_demo.php on line 7


array(3) {
  [0]=>
  string(5) "Apfel"
  [1]=>
  string(5) "Birne"
  [2]=>
  string(5) "Apfel"
}
array(2) {
  ["Apfel"]=>
  int(2)
  ["Birne"]=>
  int(1)
}

Klar, man kann entweder einen Dual-Pass-Ansatz wählen und erst die Werte, dann die Häufigkeit ermitteln. Man kann auch bei jedem Wert schauen ob er schon existiert und dann alternativ den Wert mit 1 initialisieren oder sonst inkrementieren. Ist dann "sauberer" Code, aber weder performant noch besser lesbar. :nut:

Also, Fehler unterdrücken und sich jedesmal unwohl fühlen, weil das ja "unsauber" ist... :suspect: :oops:
ausblenden PHP-Quelltext
1:
2:
foreach ($a as $key)
  @$histo[$key]++;

Was mache ich falsch, was übersehe ich, ist das wirklich von den PHP-Entwicklern so beabsichtigt? Ich kann das irgendwie nicht glauben... :gruebel:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19274
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 26.06.23 01:50 
Was spricht denn für diesen Zweck gegen array_count_values?

Für andere Zwecke gibt es nun (seit 7.4) den null coalescing assignment operator ??=, mit dem man einen Arrayeintrag zuweisen und dabei ohne Warnung automatisch erstellen kann. Den gibt es leider nicht für den Inkrement-Operator. So etwas wie ??++ wäre schon sehr hilfreich.

Und ja, das ist so beabsichtigt, denn oft fallen Fehler bei der Initialisierung der Arraywerte nicht auf. Was, wenn du eben nicht 0 brauchtest, wenn der Wert noch nicht existiert? Da du mit dem Quelltext ja sagst, dass du dem Wert etwas zuweisen möchtest, finde ich die Warnung folgerichtig. Aber ja, ich habe es in der Vergangenheit auch schon so verwendet. ;-)


Zuletzt bearbeitet von jaenicke am Mo 26.06.23 02:05, insgesamt 2-mal bearbeitet
Narses Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 26.06.23 02:00 
Moin!

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Was spricht denn für diesen Zweck gegen array_count_values?
Die Funktion kann nur Strings und Ints zählen, das ist dem simplen Beispiel geschuldet. Es geht natürlich nicht immer/nur um Strings oder Ints, also keine allgemeine Lösung. :nixweiss:

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Für andere Zwecke gibt es nun (seit 7.4) den null coalescing assignment operator ??=, mit dem man einen Arrayeintrag zuweisen und dabei ohne Warnung automatisch erstellen kann. Den gibt es leider nicht für den Inkrement-Operator. So etwas wie ??++ wäre schon sehr hilfreich.
Tja, den Operator ??++ fände ich auch schön. ;)

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Und ja, das ist so beabsichtigt, denn oft fallen Fehler bei der Initialisierung der Arraywerte nicht auf. Was, wenn du eben nicht 0 brauchtest, wenn der Wert noch nicht existiert? Da du mit dem Quelltext ja sagst, dass du dem Wert etwas zuweisen möchtest, finde ich die Warnung folgerichtig, wenn es den noch nicht gibt.
Srsly? :suspect: Was sollte ich mit ++ wohl wollen, den Zeiger auf das nächste Objekt verschieben? Und ein Wert, der nicht vorhanden ist, als 0 anzunehmen, tun wir ja auch an anderen Stellen, also "realitätsfern" ist was anderes... :roll:

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Aber ja, ich habe es in der Vergangenheit auch schon so verwendet. ;-)
:zwinker:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19274
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 26.06.23 02:05 
Die kürzeste Version ohne Warnung dürfte diese sein:
ausblenden PHP-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
function inc(&$item) {
    $item++;
}
$a = array('Apfel''Birne''Apfel');
foreach ($a as $key)
  inc($histo[$key]);
var_dump($a);
var_dump($histo);

Das lohnt sich natürlich nur, wenn du es öfter ersetzen möchtest. Ob das für alle Fälle geht, weiß ich nicht.

Für diesen Beitrag haben gedankt: Narses