Возможно, это немного устарело, но вот приходят мои 2 цента ...
Не думаю, что предоставление доступа к приватным методам через __call () - хорошая идея. Если у вас есть метод, который вы действительно не хотите вызывать вне своего объекта, у вас нет способа избежать этого.
Я думаю, что еще одним элегантным решением должно быть создание какого-то универсального прокси-сервера / decorator и с помощью __call () внутри него. Позвольте мне показать, как:
class Proxy
{
private $proxifiedClass;
function __construct($proxifiedClass)
{
$this->proxifiedClass = $proxifiedClass;
}
public function __call($methodName, $arguments)
{
if (is_callable(
array($this->proxifiedClass, $methodName)))
{
doSomethingBeforeCall();
call_user_func(array($this->proxifiedClass, $methodName), $arguments);
doSomethingAfterCall();
}
else
{
$class = get_class($this->proxifiedClass);
throw new \BadMethodCallException("No callable method $methodName at $class class");
}
}
private function doSomethingBeforeCall()
{
echo 'Before call';
//code here
}
private function doSomethingAfterCall()
{
echo 'After call';
//code here
}
}
Теперь просто тестовый класс:
class Test
{
public function methodOne()
{
echo 'Method one';
}
public function methodTwo()
{
echo 'Method two';
}
private function methodThree()
{
echo 'Method three';
}
}
И все, что вам нужно сделать, это:
$obj = new Proxy(new Test());
$obj->methodOne();
$obj->methodTwo();
$obj->methodThree(); // This will fail, methodThree is private
Преимущества:
1) Вам просто нужен один прокси-класс, и он будет работать со всеми вашими объектами. 2) Вы не будете неуважительно относиться к правилам доступности. 3) Вам не нужно менять проксифицированные объекты.
Недостаток: вы потеряете приземление / контракт после обертывания исходного объекта. Если вы используете тип hinting с частотой, возможно, это проблема.
У вас есть два простых варианта.
Если вы хотите сделать это в качестве учебного упражнения, загляните в классы System.IO.
System.IO.File.Move(source$, destination$) will suffice.
Вы можете улучшить это с помощью некоторой проверки ошибок, такой как
System.IO.Directory.Exists(sourcePath$)
System.IO.Directory.Exists(destPath$)
Затем вы можете поиграть с форматированием строк и обработкой ошибок, как вам угодно.
Если Все, что вы делаете , это копировать файл, и это все ваше программное обеспечение, я бы предложил вместо этого сделать это в CMD.
Этот же подход может быть вызван из VB при необходимости. Process.Start (флаги "ROBOCOPY" & amp; source $ & amp; "" & amp; destination $ & amp; "" & amp;)
Преимущество этого состоит в том, что это отдельный процесс для вашего основного кода, который означает, что вы можете оставить очень большой файл для копирования в течение длительного периода времени без зависания собственного кода.
''' <summary>
''' Copies the file at destination Source to the folder DestinationPath (and creates the folder if it doesn't exist)
''' </summary>
''' <param name="Source">Format C:\Users\username\documents\randomstuff\unnecessaryfolder\newfolder\myfile.txt</param>
''' <param name="DestinationPath">Format (and Default path) C:\Users\username\Desktop\ </param>
Public Sub MoveFile(Source As String, DestinationPath As String)
If DestinationPath = "" Then
DestinationPath = "C:\Users\" & My.User.Name & "\Desktop\" 'default path
End If
Dim FileName
Dim src() As String = Source.Split("\")
FileName = src(src.Count - 1) 'returns the name of the file in the full path
Try
If Not IO.File.Exists(Source) Then Throw New Exception("Wrong file, you plonka!")
If Not IO.Directory.Exists(DestinationPath) Then IO.Directory.CreateDirectory(DestinationPath)
IO.File.Copy(Source, DestinationPath & FileName)
Catch ex As Exception
Throw ex
End Try
End Sub