Как вы можете видеть, люди предлагают вам максимально использовать подготовленные заявления. Это не так, но когда ваш запрос выполняется всего один раз за процесс, будет небольшое снижение производительности.
Я столкнулся с этой проблемой, но я думаю, что решил ее в очень сложном пути - как хакеры используют, чтобы избежать использования кавычек. Я использовал это в сочетании с эмулированными подготовленными заявлениями. Я использую его, чтобы предотвратить все возможные типы инъекций SQL. Так, например, запрос: Будет: или Hex - идеальный выход. В комментариях было некоторое обсуждение, поэтому я, наконец, хочу дать понять. Эти два подхода очень похожи, но в некоторых отношениях они немного различаются: Префикс ** 0x ** может использоваться только для столбцов данных, таких как char, varchar, text, block, binary, и т. д. Кроме того, его использование немного сложно, если вы собираетесь вставить пустую строку. Вам придется полностью заменить его на UNHEX () работает в любом столбце; вам не нужно беспокоиться о пустой строке. Обратите внимание, что этот шестиугольный метод часто используется как атака SQL-инъекции, где целые числа точно так же, как и строки Например, если вы просто делаете что-то вроде этого: атака может очень легко ввести вас . Рассмотрим следующий введенный код, возвращенный из вашего скрипта: SELECT ... WHERE id = -1 union all select table_name from information_schema.tables и теперь просто извлеките структуру таблицы: SELECT ... WHERE id = -1 union all select column_name from information_schema.column где table_name = 0x61727469636c65 И тогда просто выберите нужные данные. Разве это не круто? Но если кодер инъекционного сайта будет шестнадцатеричным, инъекция не будет возможна, потому что запрос будет выглядеть следующим образом: Мой подход:
sprintf("SELECT 1,2,3 FROM table WHERE 4 = %u", $input);
mysql_hex_string()
, в PHP вы можете использовать bin2hex()
. Не беспокойтесь о том, что экранированная строка будет иметь размер в 2 раза по сравнению с исходной длиной, потому что даже если вы используете mysql_real_escape_string
, PHP должен выделять одну и ту же емкость ((2*input_length)+1)
, что то же самое. 0x
или использовать функцию MySQL UNHEX
. SELECT password FROM users WHERE name = 'root'
SELECT password FROM users WHERE name = 0x726f6f74
SELECT password FROM users WHERE name = UNHEX('726f6f74')
Разница между функцией UNHEX и префиксом 0x
''
, или вы получите сообщение об ошибке. Hex-методы часто используются в качестве атак
mysql_real_escape_string
. Тогда вы можете избежать использования кавычек. "SELECT title FROM article WHERE id = " . mysql_real_escape_string($_GET["id"])
SELECT ... WHERE id = UNHEX('2d312075...3635')
читайте это .
"Спецификатор открытого доступа указывает, что интерфейс может использоваться любым классом в любом пакете. , Если Вы не определяете, что интерфейс общедоступен, Ваш интерфейс будет доступен только для классов, определенных в том же пакете как интерфейс ".
это, что Вы хотите?
Когда я бодал против этого, я использую пакет доступный внутренний или вложенный класс для реализации интерфейса, продвигая реализованный метод из общедоступного класса.
Обычно это - потому что у меня есть класс с определенным общедоступным API, который должен реализовать что-то еще для получения, это - сделанное задание (довольно часто, потому что что-то еще было обратным вызовом, замаскированным как интерфейс < grin>) - это происходит много с вещами как Сопоставимый. Я не хочу общедоступный API, загрязненный (вынужденная общественность) интерфейсная реализация.
Hope это помогает.
кроме того, если Вы действительно хотите методы, получил доступ только пакетом, Вы не хотите защищенный спецификатор объема, Вы хотите (опущенный) спецификатор объема значения по умолчанию. Используя защищенный, конечно, позволит подклассам видеть методы.
BTW, я думаю, что причина, методы интерфейса выведены для общественности, состоит в том, потому что это - очень исключение для имения интерфейса, который только реализован классами в том же пакете; они очень чаще всего вызываются чем-то в другом пакете, что означает, что они должны быть общедоступными.
Вы классифицируете, может использовать защиту пакета и все еще реализовать интерфейс:
class Foo implements Runnable
{
public void run()
{
}
}
, Если Вы хотите, чтобы некоторые методы были защищены / пакет и другие не, он кажется, что Ваши классы несут больше чем одну ответственность и должны быть разделены на несколько.
Редактирование после чтения комментариев к этому и другим ответам:
, Если Ваш так или иначе думают, что видимость метода влияет на способность вызвать тот метод, думайте снова. Не идя в экстремальные значения, Вы не можете препятствовать тому, чтобы кто-то использовал отражение, чтобы определить методы Вашего класса и вызвать их. Однако это - надуманный вопрос: если кто-то не пытается взломать Ваш код, они не собираются вызывать случайные методы.
Вместо этого думайте частный / защищенные методы как определение контракта для подклассов и используйте интерфейсы для определения контракта с внешним миром.
, О, и человеку, который решил, мой пример должен использовать K& R заключение в фигурные скобки: если это определяется в терминах Сервиса, уверенного. Иначе разве Вы не можете найти, что что-нибудь лучше делает с Вашим временем?
Этот вопрос основан на неправильном операторе:
я знаю, что интерфейс должен быть общедоступен
Едва ли, у Вас могут быть интерфейсы с модификатором доступа по умолчанию.
проблема, я не могу сделать интерфейс, или реализованные методы защитили
Здесь, это:
C:\oreyes\cosas\java\interfaces>type a\*.java
a\Inter.java
package a;
interface Inter {
public void face();
}
a\Face.java
package a;
class Face implements Inter {
public void face() {
System.out.println( "face" );
}
}
C:\oreyes\cosas\java\interfaces>type b\*.java
b\Test.java
package b;
import a.Inter;
import a.Face;
public class Test {
public static void main( String [] args ) {
Inter inter = new Face();
inter.face();
}
}
C:\oreyes\cosas\java\interfaces>javac -d . a\*.java b\Test.java
b\Test.java:2: a.Inter is not public in a; cannot be accessed from outside package
import a.Inter;
^
b\Test.java:3: a.Face is not public in a; cannot be accessed from outside package
import a.Face;
^
b\Test.java:7: cannot find symbol
symbol : class Inter
location: class b.Test
Inter inter = new Face();
^
b\Test.java:7: cannot find symbol
symbol : class Face
location: class b.Test
Inter inter = new Face();
^
4 errors
C:\oreyes\cosas\java\interfaces>
Следовательно, достигая, что Вы хотели, предотвращают интерфейс и использование класса за пределами пакета.
Вот то, как это могло быть сделано с помощью абстрактных классов.
единственное неудобное - то, что это заставляет Вас "разделить на подклассы".
Согласно руководству Java, необходимо последовать тому совету "большинство" времен, но я думаю в этой ситуации, это будет в порядке.
public abstract class Ab {
protected abstract void method();
abstract void otherMethod();
public static void main( String [] args ) {
Ab a = new AbImpl();
a.method();
a.otherMethod();
}
}
class AbImpl extends Ab {
protected void method(){
System.out.println( "method invoked from: " + this.getClass().getName() );
}
void otherMethod(){
System.out.println("This time \"default\" access from: " + this.getClass().getName() );
}
}
Можно пойти с инкапсуляцией вместо наследования.
таким образом, создайте свой класс (который ничего не наследует), и в нем, имейте экземпляр объекта, который Вы хотите расширить.
Тогда можно представить только, что Вы хотите.
очевидный недостаток этого - то, что Вы должны явно методы передачи для всего, что Вы хотите представленный. И это не будет подкласс...
Я просто создал бы абстрактный класс. Нет никакого вреда в нем.