PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr

PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr (https://www.php-resource.de/forum/)
-   PHP Developer Forum (https://www.php-resource.de/forum/php-developer-forum/)
-   -   Verbindung erkennen? (https://www.php-resource.de/forum/php-developer-forum/95830-verbindung-erkennen.html)

RamonaS 13-03-2009 10:26

Verbindung erkennen?
 
Hallo, ich wußte nicht was ich als betreff schreiben soll :-)

Also ich bastel gerade an einer webstatistik rum.

Nun habe ich einträge wie:

WinXP (NT 5.1)
WinVista (NT 6.0 Longhorn)
Win2K (NT 5.0)
WinServer2003 (NT 5.2)
Macintosh (Mac OS)
Ubuntu (Linux)
Linux
Win98
WinME (Win9x 4.90)
Win2K 2000
SonyEricsson Cellphone
Win95

Jetzt möchte ich eine verbindung zwischen diesen wörtern und meine bildern 16x16 icons herstellen

Ich kann ja mein icon schlecht "WinME (Win9x 4.90)" bennenen, ich dachte das ich das icon einfach winme.png benenne, jetzt soll php feststellen ob in dem string "winme" drin steht, geht sowas?

Es sollte rwecht flott sein, weill ich da pro monat 1000-2000 solcher unterschiedlicher einträge habe.

Die texte die hier oben stehen, habe ich im php selber so festgelegt, mit unendlich vielen zeilen die so aussehen:

elseif(preg_match("/windows nt 6.0/i",$os)) {$os='WinVista (NT 6.0 Longhorn)';}
...die ganzen Abfragen stehen in einer function drin.
Kann man das effektiver schreiben, eventuell das ganze in ein array rein?

Abraxax 13-03-2009 10:30

wenn du schon mit preg_-funktionen arbeitest, sollte dir auch geläufig sein, dass diese nach bestimmten teilen suchen können.

denn das tust du doch schon ... du suchst im string $os nach einem teilstring "windows nt 6.0".

wenn du nur nach "winme" suchen willst, musst du das halt eintragen.

----

alternativ zu preg_match() könntest du auch strstr() nehmen. wenn du wirklich nur solche einfachen vergleiche brauchst.

ghostgambler 13-03-2009 10:31

PHP-Code:

<?php
$name 
"WinXP (NT 5.1)";
$icon_name strtolower(substr($name0strpos($name" ")+1));


fireweasel 13-03-2009 11:27

Re: Verbindung erkennen?
 
Zitat:

Original geschrieben von RamonaS
Hallo, ich wußte nicht was ich als betreff schreiben soll :-)

Also ich bastel gerade an einer webstatistik rum.

Nun habe ich einträge wie:

WinXP (NT 5.1)
WinVista (NT 6.0 Longhorn)
Win2K (NT 5.0)
WinServer2003 (NT 5.2)
Macintosh (Mac OS)
Ubuntu (Linux)
Linux
Win98
WinME (Win9x 4.90)
Win2K 2000
SonyEricsson Cellphone
Win95

Jetzt möchte ich eine verbindung zwischen diesen wörtern und meine bildern 16x16 icons herstellen

Ich kann ja mein icon schlecht "WinME (Win9x 4.90)" bennenen, ...
Wieso eigentlich nicht? Das ist ein ganz legaler Dateiname. Mir würde jetzt kein halbwegs modernes Filesystem einfallen, was mit diesen Zeichen Probleme hätte.

Zitat:

... ich dachte das ich das icon einfach winme.png benenne, jetzt soll php feststellen ob in dem string "winme" drin steht, geht sowas?
Klar geht das. Aber du solltest dir vorher überlegen, wonach du suchst und wie du die gefundenen Muster zuordnest.

Code:

WinME (Win9x 4.90)       
...
Win95

Erstens unterscheidet sich WinME (aus der Sicht eines Webservers) nicht sooo großartig von Windoze 98 oder 95 oder irgendwelchen Service-Releases dieser Betriebssysteme. Und zweitens outet sich das "WinME" ja auch im weiteren Verlauf als "Win9x" ...
Du solltest auch nicht vergessen, dass die User-Agent-Kennung auch "lügen" kann.

Zitat:

Es sollte rwecht flott sein, weill ich da pro monat 1000-2000 solcher unterschiedlicher einträge habe.
2000 pro Monat ist doch nicht viel. ;)

Zitat:

Die texte die hier oben stehen, habe ich im php selber so festgelegt, mit unendlich vielen zeilen die so aussehen:
Unendlich viele Zeilen? Das ist schlecht. Mit Arrays als Suchmuster kann aber leider nur preg_replace() umgehen. Mal sehen, ob sich da was zaubern lässt.

*nachträglich_einschieb*
Und natürlich kann auch str_ireplace() mit Arrays umgehen. Deine Suchmuster-Strings werden sicher aus User-Agent-Kennungen gewonnen werden, die eher selten Nicht-ASCII-Zeichen enthalten. Außerdem entfällt das umständliche Aufbereiten des Suchmuster-Arrays (siehe Link im nächsten Absatz).
Schneller als preg_replace() mit Modifikator 'i' dürfte das Suchen-und-Ersetzen allerdings nicht werden.

Zumindest für das Muster-Suchen mit preg_replace() gibts schon eine Lösung.

Zitat:

...die ganzen Abfragen stehen in einer function drin.
Kann man das effektiver schreiben, eventuell das ganze in ein array rein?
Sicher. Ein vergleichbares Problem ist das Ersetzen von bestimmten Zeichenkombinationen mit Smiley-Grafiken in (bspw.) BBCode-Parsern. Vielleicht findet sich da eine effizientere Lösung.

Zum Beispiel die hier.

RamonaS 13-03-2009 11:28

@ghostgambler

dein vorschlag mit
$icon_name = strtolower(substr($name, 0, strpos($name, " ")+1));
ist nicht schlecht, allerdings kann man nicht immer rechnen das ein Leerzeichen da drin steht:-(


So habe ich das ganze bisher aufgebaut, läuft recht gut, allerdings weiß ich nicht wie schnell das ist wenn viele durchgänge sind.

So wie dieser aufgabu ist, habe ich nochmal das gleiche für
referer, hostadressen, browsertyp, sprache und bruserherkunftsland

kann man hier was optimieren? Ich möchte nicht später alles neu machen, da setze ich lieber gleich auf "schnelle abwicklung" :-)

for($i=0; $i<$total; $i++)
{$zt=explode($utr,trim($arr[$i]));
$osystem[]=getOS($zt[5]); # inhalt von $zt[5] z.B. => Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.20
}

$diff=array_count_values($osystem);
@arsort($diff);

foreach($diff as $k=>$v)
{if($k=="?" or $k==""){$bad=$v; continue;}
$os_img=strtolower(substr($k,0,5));
echo " <tr>\n";
echo " <td class='sp1'><img class='ico' src='$os_dir/$os_img.gif' />&nbsp;$k</td><td class='sp2'>".$v."</td>\n";
echo " </tr>\n";
}
echo " </table>\n\n";


function getOS($zt5) # ClientOS ermitteln $zt5=UserAgent
{if (preg_match("/kubuntu/i",$zt5)) {$zt5='Kubuntu (Linux)';}
elseif(preg_match("/ubuntu/i",$zt5)) {$zt5='Ubuntu (Linux)';}
elseif(preg_match("/linux/i",$zt5)) {$zt5='Linux';}
elseif(preg_match("/macintosh/i",$zt5)) {$zt5='Macintosh (Mac OS)';}
elseif(preg_match("/sunos/i",$zt5)) {$zt5='SunOS (Sun Microsystems Inc.)';}
elseif(preg_match("/os\/2/i",$zt5)) {$zt5='Operating System/2 (IBM OS/2)';}
elseif(preg_match("/windows nt 6.0/i",$zt5)) {$zt5='WinVista (NT 6.0 Longhorn)';}
...
}

sorry ich hab das mit dem php-code nicht gefunden, wenn ich den button php klicke kann ich nur eine zeile einfügen in dem alert-fenster:-(

pascal007 13-03-2009 11:54

Ich würde einfach die md5-Summe der Strings als Bildnamen nehmen. Das ist eindeutig.

PHP-Code:

$bild md5("Linux").".png";

echo
"<img src=\"$bild\" alt=\"Linux\" />"


Peacie 13-03-2009 12:02

da du ja selbst für die ergebnisse deiner webstats bzw für die benennung der BS verantwortlich bis könnte man das zuordnen der bilder so in etwa lösen...

PHP-Code:

$bild["linux"]=array("Ubuntu (Linux)""Linux");
$bild["windows"]=array("WinXP (NT 5.1)""WinVista (NT 6.0 Longhorn)");

$DeinErgebniss "WinVista (NT 6.0 Longhorn)";
while (list (
$key$val) = each ($bild))  

    if ( 
in_array $DeinErgebniss$val ) ) 
    {
    echo 
"nu muss ich bild <u>".$key."</u> nehmen";
    }


natürlich noch in ne passende funktion bauen, die dir dann nur noch den bildnamen zurückgibt, aber dafür war ich grad zu faul :P

Peacie 13-03-2009 12:04

Zitat:

Original geschrieben von pascal007
Ich würde einfach die md5-Summe der Strings als Bildnamen nehmen. Das ist eindeutig.

PHP-Code:

$bild md5("Linux").".png";

echo
"<img src=\"$bild\" alt=\"Linux\" />"


scheitert nur daran, wenn man nicht für jedes xbeliebige bs ein neues icon bauen will.

wenn man für die xx linux versionen immer ein neues icon bräuchte, oh je :D
aber ansonsten gute idee

pascal007 13-03-2009 13:29

Aha ich dachte es würde immer Linux stehen :D... ja vllt will man ja das Logo der jeweiligen Dispru nehmen... wer weiss ;).

fireweasel 13-03-2009 14:34

PHP-Code:

/// wird nur gebraucht, um Fehlermeldungen auszugeben
///
function _error_throw() {
  static 
$php_error = array (
    
E_NOTICE => E_USER_NOTICE,
    
E_WARNING => E_USER_WARNING,
    
E_ERROR => E_USER_ERROR,
  );
  
$args func_get_args();
  
$error = !is_int($args[key($args)]) ? E_WARNING array_shift($args);
  
$msg = (count($args) >= 1) ? vsprintf(array_shift($args), $args) : 'No Error.';
  return 
trigger_error($msg, isset($php_error[$error]) ? $php_error[$error] : $error);
}

/// Die eigentliche Suchen-und-Ersetzen-Funktion

/// filter user agent string
/// return BOOL success in init-mode | STR() in search-n-replace-mode
function ua_filter(
  
$user_agent '' /// LIST of user agent strings
) {
  
// init the search-n-replace ARRAYS
  
static $search = array ();
  static 
$replace = array ();
  if (
is_array($user_agent)) {
    
// check validity of input
    
foreach ($user_agent as $key => $value) {
      
// erlaubte Delimiter im PCRE sind: '/', '#' und '='
      
if (!preg_match('/\A([\/#=]).*\\1[imsxeADSUXu]*\z/'$key)) {
        unset(
$user_agent[$key]);
        
$key '/\A.*?'preg_quote($key'/') . '.*\z/is';
        
$user_agent[$key] = $value;
      }
      
ob_start();
      
preg_match($key'');
      if (
strlen(ob_get_clean())) {
        
// invalid pcre in $user_agent[$key]
        
_error_throw(E_NOTICE'invalid pcre in %s (key: %s)'$value$key);
        return 
FALSE;
      }
    }
    
$search array_keys($user_agent);
    
$replace array_values($user_agent);
    
//debug_writefln('search: %s replace: %s', $search, $replace);
    
return TRUE;
  }
  
  if (empty(
$search)) {
    
// forgot to init?
    
_error_throw(E_WARNING'forgot to init?');
    return 
FALSE;
  }

  if (!
is_string($user_agent)) {
    
// invalid argument
    
_error_throw(
      
E_WARNING
      
'parameter $user_agent must be of type STRING in search-mode, ARRAY in init-mode');
    return 
FALSE;
  }
  
$count 0;
  
$new preg_replace($search$replace$user_agent1$count);
  return (bool) 
$count $new '-unknown-';


Ein Objekt würde sich hier übrigens besser machen als eine einzelne Funktion.

Und so wird das Ganze angewandt:

PHP-Code:

// deine 1000--2000 User-Agent/Betriebssystemkennungen
$ua_strings = array (
  
'WinXP (NT 5.1)',
  
'WinVista (NT 6.0 Longhorn)',
  
'Win2K (NT 5.0)',
  
'WinServer2003 (NT 5.2)',
  
'Macintosh (Mac OS)',
  
'Ubuntu (Linux)',
  
'Linux',
  
'Win98',
  
'WinME (Win9x 4.90)',
  
'Win2K 2000',
  
'SonyEricsson Cellphone',
  
'Win95',
);

// Ein assoziatives Array zum Suchen-und-Ersetzen
// Die KEYS sind die Suchmuster:
//     PCRE sind erlaubt, sollten aber die ganze Stringlänge erfassen 
// Die VALUES sind Icon-Namen: 
//     Pfade und Endungen kannst hinterher hinzufügen

// search 'n replace array
$snr = array (
  
// Beispiele für PCRE
  
'/\A.*?win9[58x].*\z/i' => 'win9x',
  
'/\A.*?(linux).*\z/i' => 'pinguin',

  
// Beispiel für gewöhnlichen Suchstring 
  //(muss im zu durchsuchenden String vorkommen)
  
'cellphone' => 'mobile',
);

// Die Funktion mit dem Suchen-und-Ersetzen-Hash füttern
// init
$result ua_filter($snr);

// Falls das scheitert, brechen wir ab
if (!$result) {
  die(
'initialization failed');
}

// Das 1000--2000-Einträge-Array wird durchgetestet
foreach ($ua_strings as & $ua) {
  
$icon_name ua_filter($ua);
  
printf('found? %s what? %s<br />'$icon_name$ua);
}
// Nicht bekannte Einträge ergeben '-unknown-',
// bekannte den "Iconnamen"
// aus dem kann man den Dateinamen basteln:
// "${os_dir}/${icon_name}.gif" 

Zitat:

Es sollte recht flott sein, weil ich da pro monat 1000-2000 solcher unterschiedlicher einträge habe.
Um die Geschwindigkeit realistisch einzuschätzen, bräuchte man mal so ein 1000-bis-2000-Einträge-Array. Auf alle Fälle dauert das Durchmustern am längsten, wenn nichts im Search-n-Replace-Array gefunden wird.

Peacie 13-03-2009 15:55

sehr nette lösung weasel
OffTopic:

hat nur son bichen was von kanonen und spatzen oder porsche und brötchen holen :D


fireweasel 13-03-2009 20:50

Worauf beziehen sich deine "kanonen"?
Die Kernfunktion, um die es eigentlich geht, ist doch nicht sooo umständlich.

Der Umstand mit der Anzeige der Fehler ist nur drin, um unnötigen Fragen vorzugreifen, wenn mal etwas schiefgeht und hinten FALSE rauskommt.

Sicher hätte ein objektorientierter Ansatz mehr Klarheit gebracht:

Code:

class ... {
  function init() {}
  function filter() {}
  function error() {}
}

Irgendwie meinte ich aber zu glauben, dass der OP Probleme mit OOP gehabt zu haben schien ... hab das wohl mit http://www.php-resource.de/forum/sho...789#post611959 verwechselt.

RamonaS 14-03-2009 00:15

@fireweasel

Haleluja, ich verneige mich :-)
Puhhh, das ist etwas viel schotter für mein wissen....ich hab mal dein script local gespeichert, ich schu mir das mal in aller ruhe an.


Andere, neue Frage poste ich mal wieder - es geht um die "zerlegung" der browsersprche + browserland.

Danke erstmal für hier und eure zahlreichen hilfen.

Peacie 14-03-2009 01:27

Zitat:

Original geschrieben von fireweasel
Worauf beziehen sich deine "kanonen"?

nene, ich find schon das du da was feines gebaut hast. mag sein das ich den TE nicht richtig verstanden hab, dachte es geht lediglich um die zuordnung von bestimmten bs typen zu wenigen grafiken


Alle Zeitangaben in WEZ +2. Es ist jetzt 12:11 Uhr.

Powered by vBulletin® Version 3.8.2 (Deutsch)
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0
[c] ebiz-consult GmbH & Co. KG