Klassen analysieren (Liste Methoden etc.)

Klein0r

Erfahrenes Mitglied
Hallo zusammen.

Ich hätte gerne auf meiner Homepage eine Art Analysetool für Klassen. Grund dafür ist mein "Modulsystem". Jede Seite erbt von einer anderen und kann gewisse Methoden von der Kindklasse überschreiben. z.B. eine Suchmethode (die ein Array mit Objekten der Suchergebnisse zurückgibt).

Nun möchte ich wissen welche Seiten die Methode implementieren. Also auf welchen Seiten ich keine Suche nutze.

Das ist nur ein Anwendungsbeispiel.

Daher möchte ich generell nähere Informationen zu einer Klasse enthalten.
Darunter:
  • Eine Liste der implementierten Interfaces
  • Eine Liste der privaten, protected und public Methoden
  • Welche Methoden von der Kindklasse überschrieben wurden
  • usw.

Geht sowas einfach?

lg
 
Hey danke!

Ob eine Methode aus get_class_methods($class) vererbt wurde bekomme ich nicht raus oder?

Weiterhin wüsste ich gerne ob die Methode public, private oder protected ist und wie viele Parameter sie entgegen nimmt. Ist das zuviel verlangt? ;)

Und evt auchnoch ob sie überschrieben wurde.
Finde dazu nichts. ;)

lg
 
public <-> protected/private kannst du rauskriegen, unterscheiden kannst du das nicht...

PHP:
<?php

class foo
{
	public function bar()
	{
	
	}
	
	public function noYou()
	{
	
	}
	
	private function foobar()
	{
	
	}
}

$foo = new foo();

var_dump(is_callable(array($foo, 'bar')));
var_dump(is_callable(array($foo, 'noYou')));

Bei der Feststellung auf Vererbung könnte ich mir höchstens vorstellen, dass du einen Vergleich gegen die Elternklasse startest... Allerdings könnte es da auch einfach Probleme geben, wegen Überschreibung, u. Ä.

Anzahl der Parameter... Hm.
PHP:
<?php

function foo($bar1, $bar2, $bar3, $bar4)
{
	
}

function checkParams($func)
{
	$i = 0;
	ob_start();
	call_user_func($func);
	$msg = ob_get_contents();
	ob_end_clean();
	return $msg;
}

var_dump( checkParams( 'foo' ) );
?>

Jetzt noch die Fehlermeldung analysieren...

Allerdings ist das wirklich "dreckig" ;)
 
Alles blöd hier gerade...

Irgendwie liefert get_class_methods($class) nur die Methoden die ich auch gerade aufrufen kann bzw auf die ich Zugriff habe.

Ich habe ja eine Art Modulsystem = Jede Seite ist eine Klasse die von einer Basisklasse mit gewisser Funktionalität erbt. Das hab ich im ersten Post ja schon beschrieben ;)

Jetzt ist die Seite mit dem Namen Development (Klasse inc_admin_development) logischweise auch ein "Modul". Wenn ich nun alle Dateien Include die sich in Verzeichnis x befinden, bekomme ich für mein Modul alle Methoden aufgelistet (auch private). Für alle anderen bleiben mir allerdings die private-functions verborgen und werden garnicht mit aufgelistet.

Das stört mich gerade gewaltig.
Das Problem mit der Vererbung habe ich so gelöst wie du geschrieben hattest. Ich ermittel in einer Schleife alle Elternklassen bis ich ganz unten bin. Wenn ich dann später auf eine Methode stoße gehe ich mein "Elternarray" rückwärts durch und suche die Klasse die als erstes diese Methode implementiert.
Allerdings bekomme ich so nicht raus ob eine Klasse überschrieben ist. grrr

Mal ein wenig Code statt nur gerede:
PHP:
		$this->draw_header('Übersicht aller Klassen (Admin)');
		
		foreach (get_declared_classes() as $class) {
			// Prüfen ob es sich um eine Klasse von mir handelt
			if (substr($class, 0, 3) == CLASS_PREFIX) {
				$this->draw_content_begin();
				echo '<b>'.$class.'</b><br />';
				
				// Speichert die Klassenhierarchie mit allen Methoden
				$inherited = array();
				$parent = $class;
				while ($parent = get_parent_class($parent)) {
					echo '&raquo; '.$parent.'<br />';
					$inherited[] = $parent;
				}
				
				echo '<br />
				<table class="details">';
				
				foreach (get_class_methods($class) as $method) {
					
					$methodOfClass = $class;
					
					$found = false;
					for ($i = count($inherited) - 1; $i >= 0; $i--) {
						if (!$found && in_array($method, get_class_methods($inherited[$i]))) {
							$methodOfClass = $inherited[$i];
							$found = true;
						}
					}
					
					echo '
					<tr>
						<td class="tableleft">
							'.$methodOfClass.'
						</td>
						<td class="tableright">
							'.$method.'()
						</td>
					</tr>
					';
					
				}
				
				echo '</table>';
				
				$this->draw_content_end();
				$this->draw_devider();
			}
		}
		
		$this->draw_bottom();

Jemand noch eine Idee?

Mit der Anzahl der Parameter habe ich noch nicht so ganz verstanden...
Werde mir mal das Manual zu den einzelnen Methoden ansehen.

lg
 
Wenn mal alles so einfach wär!
Vielen Dank :)

PHP:
		$this->draw_header('Übersicht aller Klassen (Admin)');
		
		$classes = get_declared_classes();
		asort($classes);
		foreach ($classes as $class) {
			// Prüfen ob es sich um eine Klasse von mir handelt
			if (substr($class, 0, 3) == CLASS_PREFIX) {
				$reflect = new ReflectionClass($class);
				
				$this->draw_content_begin();
				
				$abstract_class = $reflect->isAbstract() ? '<i>abstract</i> ' : '';
				echo $abstract_class.'<b>'.$class.'</b> ('.($reflect->getEndline()-$reflect->getStartLine()).' Zeilen)<br />'; 
				
				// Gibt die Klassenhierarchie aus
				$parent = $reflect;
				while (($parent = $parent->getParentClass()) != null) {
					echo '&raquo; '.$parent->getName().'<br />';
				}
				
				$this->draw_content_end();
				$this->draw_content_begin();
				
				echo '<table class="details">';
				
				foreach ($reflect->getMethods() as $method) {
					
					// Nur die Methoden anzeigen die nicht vererbt wurden
					if ($method->getDeclaringClass()->getName() == $class) {
						
						$params = '';
						foreach ($method->getParameters() as $param) {
							$params .= ($param->isPassedByReference()) ? '&' : '';
							$params .= '$'.$param->getName().', ';
						}
						
						$modifiers = implode(' ', Reflection::getModifierNames($method->getModifiers()));
						
						echo '
						<tr>
							<td class="tableleft">
								'.$modifiers.'
							</td>
							<td class="tableright">
								'.$method->getName().'('.$params.')
							</td>
						</tr>
						';
						
					}
					
				}
				
				echo '</table>';
				
				$this->draw_content_end();
				$this->draw_devider();
			}
		}
		
		$this->draw_bottom();

lg
 
Allerdings habe ich noch keinen einfachen Weg gefunden um herauszufinden ob eine Methoden überschrieben ist oder nicht.

Oder ich bin einfach zu blöd zum lesen.
Mach es erstmal wie vorher - nur das es jetzt ein wenig einfacher ist ;)

lg
 
Zu diesem Thema stellt PHP auch seit der Version 5 eine Reihe an Klassen bereit. Wollte mich mal damit beschäftigen, bin aber noch nicht richtig dazu gekommen. Über diese kann man aber sehr sehr detallierte informationen Erhalten. Stichwort Reflections.
MfG, Andy

//EDIT: Oh den Einwurf gab es bereits! :-(
 
Zuletzt bearbeitet von einem Moderator:
Zurück